`
xitonga
  • 浏览: 596466 次
文章分类
社区版块
存档分类
最新评论

DP31 取大小游戏中的最优策略(附:如何对DP[0][n]进行对角线递推) Optimal Strategy for a Game @geeksforgeeks

 
阅读更多

Problem statement: Consider a row of n coins of values v1 . . . vn, where n is even. We play a game against an opponent by alternating turns. In each turn, a player selects either the first or last coin from the row,removes it from the row permanently, and receives the value of the coin. Determine the maximum possible amount of money we can definitely win if we move first.

Note: The opponent is as clever as the user.

Let us understand the problem with few examples:

1.5, 3, 7, 10 : The user collects maximum value as 15(10 + 5)

2.8, 15, 3, 7 : The user collects maximum value as 22(7 + 15)

Does choosing the best at each move give an optimal solution?

No. In the second example, this is how the game can finish:

1.
…….User chooses 8.
…….Opponent chooses 15.
…….User chooses 7.
…….Opponent chooses 3.
Total value collected by user is 15(8 + 7)

2.
…….User chooses 7.
…….Opponent chooses 8.
…….User chooses 15.
…….Opponent chooses 3.
Total value collected by user is 22(7 + 15)

So if the user follows the second game state, maximum value can be collected although the first move is not the best.

There are two choices:
1.The user chooses the ith coin with value Vi: The opponent either chooses (i+1)th coin or jth coin. The opponent intends to choose the coin which leaves the user with minimum value.
i.e. The user can collect the value Vi + min(F(i+2, j), F(i+1, j-1) )
coinGame1

2.The user chooses the jth coin with value Vj: The opponent either chooses ith coin or (j-1)th coin. The opponent intends to choose the coin which leaves the user with minimum value.
i.e. The user can collect the value Vj + min(F(i+1, j-1), F(i, j-2) )
coinGame2

Following is recursive solution that is based on above two choices. We take the maximum of two choices.

F(i, j)  represents the maximum value the user can collect from 
         i'th coin to j'th coin.

    F(i, j)  = Max(Vi + min(F(i+2, j), F(i+1, j-1) ), 
                   Vj + min(F(i+1, j-1), F(i, j-2) )) 
Base Cases
    F(i, j)  = Vi           If j == i
    F(i, j)  = max(Vi, Vj)  If j == i+1

Why Dynamic Programming?
The above relation exhibits overlapping sub-problems. In the above relation, F(i+1, j-1) is calculated twice.


很有意思的博弈问题,重要的一点是贪心法在这里是不行的,前面已经举了反证。

另外很重要的一点是对求dp[0][n]而不是dp[m][m]的问题,如何写for循环。文章里说要从对角线开始向右上角递推。

比如:

The below table represents the stored values for the string abcde.

a b c d e
----------
0 1 2 3 4
0 0 1 2 3 
0 0 0 1 2 
0 0 0 0 1 
0 0 0 0 0

How to fill the table?
The table should be filled in diagonal fashion. For the string abcde, 0….4, the following should be order in which the table is filled:

Gap = 1:
(0, 1) (1, 2) (2, 3) (3, 4)

Gap = 2:
(0, 2) (1, 3) (2, 4)

Gap = 3:
(0, 3) (1, 4)

Gap = 4:
(0, 4)

可以用以下代码得到:

用一个gap变量作为l和h之间的距离,然后l和h一起前进,直到h碰到边界n,因为l在左上方,h在右下方,所以肯定h先碰到右边界!

// Fill the table
    for (gap = 1; gap < n; ++gap)
        for (l = 0, h = gap; h < n; ++l, ++h)
            table[l][h] = (str[l] == str[h])? table[l+1][h-1] :
                          (min(table[l][h-1], table[l+1][h]) + 1);



package DP;

public class OptimalGameStrategy {

	public static void main(String[] args) {
		int[] A = {8, 15, 3, 7};
		int[] B = {2, 2, 2, 2};
		int[] C = {20, 30, 2, 2, 2, 10};
		System.out.println(optimalStrategyOfGameRec(A, 0, A.length-1));
		System.out.println(optimalStrategyOfGame(A, A.length));
		System.out.println(optimalStrategyOfGameRec(B, 0, B.length-1));
		System.out.println(optimalStrategyOfGame(B, B.length));
		System.out.println(optimalStrategyOfGameRec(C, 0, C.length-1));
		System.out.println(optimalStrategyOfGame(C, C.length));
		
	}
	
	
	public static int optimalStrategyOfGameRec(int[] A, int begin, int end){
		if(begin == end){		// 只剩下一枚硬币时,只能取那枚
			return A[begin];
		}
		if(begin+1 == end){	// 只剩下两枚时,取大的那枚
			return Math.max(A[begin], A[end]);
		}
		
		// 如果我去开头那枚,因为对手会拿较大那枚,所以留下的是较小的选择,看图
		int a = A[begin] + Math.min(optimalStrategyOfGameRec(A, begin+2, end), 
											   optimalStrategyOfGameRec(A, begin+1, end-1));
		// 如果我去拿结尾那枚,同理
		int b = A[end] + Math.min(optimalStrategyOfGameRec(A, begin+1, end-1), 
											 optimalStrategyOfGameRec(A, begin, end-2));
		return Math.max(a, b);		// 做最合算的选择
	}
	
	
	// Returns optimal value possible that a player can collect from
	// an array of coins of size n. Note than n must be even
	public static int optimalStrategyOfGame(int[] A, int n){
		int[][] dp = new int[n][n];	//dp[begin][end]保存从序号为begin到end的coin序列能取得的最大值
		
		// Fill table using above recursive formula. Note that the table
	    // is filled in diagonal fashion (similar to http://goo.gl/PQqoS),
	    // from diagonal elements to table[0][n-1] which is the result.
		for(int gap=0; gap<n; gap++){
			int begin=0, end=gap;
			while(end < n){
				// 检测条件为右上角
				int x = begin+2<=end ? dp[begin+2][end] : 0;
				int y = begin+1<=end-1 ? dp[begin+1][end-1] : 0;
				int z = begin<end-2 ? dp[begin][end-2] : 0;
				
				dp[begin][end] = Math.max(A[begin]+Math.min(x, y), 
										   A[end]+Math.min(y, z));
				begin++;
				end++;
			}
		}
		
		return dp[0][n-1];
	}

}


http://www.geeksforgeeks.org/dynamic-programming-set-31-optimal-strategy-for-a-game/

http://www.geeksforgeeks.org/dynamic-programming-set-28-minimum-insertions-to-form-a-palindrome/

分享到:
评论

相关推荐

    matlab最优捕鱼策略.ppt

    Matlab最优捕鱼策略.ppt是一个关于 Matlab 中最优捕鱼策略的 ppt 文档。该文档主要介绍了如何使用 Matlab 建立数学模型来实现可持续捕捞,并在此基础上得到最高年收获量。 在该文档中,作者首先提出了一个问题:...

    归纳策略之递推算法

    有一类试题,每相邻两项数之间的变化有一定的规律性,我们可将这种规律归纳成如下简捷的递推关系式:F(n)=G(F(n-1)) 这就在数的序列中,建立起后项和前项之间的关系。然后从初始条件(或最终结果)入手,一步步地按...

    《算法与数据结构》—递推方程及算法分析

    本文将对递推方程的概念、算法设计和时间复杂度分析进行详细的介绍,并通过几个例子来加深对递推方程的理解。 递推方程的概念 递推方程是一种定义数列或序列的数学表达式,每个元素的值都可以用前一个元素或前几个...

    递推经典习题:偶数个三

    编程求所有的n位数中,有几个数有偶数个数字是3, (输入格式):输入n (输出格式):输出方案对12345取模的值

    学习常用算法之(4)递推法

    学习常用算法之递推法 递推法是一种常用的算法,用于解决某个特定问题。它是一组有限个规则,提供了解决问题的运算序列。在计算机科学中,递推法是一种重要的算法思想,它可以帮助我们解决复杂的问题。 递推法的...

    dp入门 数字三角形

    dp入门 数字三角形 人人为我型 递推式 专门为初学dp算法的新手准备

    论文研究- 经济增长模型的递推规划方法与最优平衡问题.pdf

    论文研究- 经济增长模型的递推规划方法与最优平衡问题.pdf, 递推规划是复杂经济系统的分解途径,又是一种不同模型组合与连接的方法,近几年在理论研究和实际应用中发展很快。利用递推规划方法建立的我国宏观经济模型,...

    递推式的一般代数解法

    例如汉诺塔问题的时间复杂度递推 形式为 T (n)=2T (n−1)+1 (n≥1) ,可以解出封闭形式为 T (n)=2 n −1 (设初始状态 T (0)=0 )。 因为递推式求解的重要性,许多算法书籍对其有专门介绍。Donald Knuth在Concrete ...

    将有双亲域的二叉链表进行中序遍历的递推式算法

    将有双亲域的二叉链表进行中序遍历的递推式算法

    LabVIEW十种滤波算法:限幅,中位值,算术平均,递推平均,中位值平均,限幅平均,一阶滞后,加权递推平均,消抖,限幅消抖滤波法

    十种常见的滤波算法用LabVIEW来实现,一维数组输入输出接口已配置好,程序框图有对每种滤波算法进行说明。可直接用枚举变量选择对应滤波方法,分别是: 无滤波 限幅滤波法 中位值滤波法 算术平均滤波法 递推平均滤波...

    广义系统ARMA最优递推状态估值器.rar

    广义系统ARMA最优递推状态估值器rar,广义系统 广义ARMA状态估值器,广义Wiener状态滤波器 现代时间序列分析方法

    Optimal Control Theory.pdf

    1.动态规划、贝尔曼方程、最优值函数、值与策略迭代、最短路径、马尔可夫决策过程。2. 哈密顿-雅可比-贝尔曼方程,近似方法,nite和nite hori- zon公式,随机微积分基础。3.庞特利亚金的极大原理,ODE和梯度下降法,...

    组合数学常系数线性齐次递推关系PPT课件.pptx

    例如,在递推关系a n = c 1a n - 1 + c 2a n - 2 +…+ c ka n - k中,将a n 代入特征方程式x n - c 1x n - 1 - c 2x n - 2 -…- c k x - c k = 0可以得到特征方程式。 2. 递推关系的解: 递推关系的解是...

    五种典型的递推关系(C++版)-2022-01-31(C).pdf

    "五种典型的递推关系(C++版)" 本文总结了五种典型的递推关系,包括Fibonacci数列、Hanoi塔问题、平面分割问题等。这些问题都是竞赛中经常出现的题型,每种问题都有其独特的递推关系和解法。 一、Fibonacci数列 ...

    c++递推算法详解.ppt

    递推关系为 dp[i][j] = dp[i-1][j-1] + dp[i-1][j],边界条件为 dp[0][0] = 1。 递推算法是一种非常有用的方法,可以用来解决许多类型的问题。但是,我们需要注意时间复杂度的问题,可以使用 memoization 或动态...

    递推课件-ACM 程序设计

    递推问题:递推与递归解法 递推问题的一般步骤: 一. 判断是否属于递推问题:这个没有可套用的公式,凭经验,具体问题具体考虑 如果把问题的规模缩小,得到的小问题与原问题在结构上性质上相同或相似,并且子问题与...

    基于BP神经网络递推积分PI-重复控制在微电网APF中的研究.pdf

    在仿真实验中,作者建立了并联型APF仿真模型和实验装置,并对所提出的控制策略进行了仿真对比验证。结果表明,基于BP神经网络递推积分PI-重复控制策略的APF能够显著提高响应速度和补偿精度,提高APF的鲁棒性。 本...

    基础算法 第3章 递推算法(C++版)-2020-10-08.pdf

    递推算法是数学中的一种重要方法,在计算机科学中也是一种重要的算法,广泛应用于数学的各个领域。递推算法的特点是,一个问题的求解需要一系列的计算,在已知条件和所求问题之间总存在着某种相互联系的关系。在计算...

    递归and递推习题2.doc

    问题描述:在一个凸 n 边形中,通过不相交于 n 边形内部的对角线,把 n 边形剖分成若干个三角形。不同的剖分数目用 Cn 表示。 7. 三角形最佳路径问题 三角形最佳路径问题是一个递推问题。问题描述:如下所示的由正...

    高级人工智能-强化学习补充部分:棋类游戏的贝尔曼方程1

    在棋类游戏中,贝尔曼方程可以用来计算状态值函数,从而帮助agent学习到最优的策略。状态值函数是指在某个状态下,agent能够获得的预期回报。贝尔曼方程通过递推的方式计算状态值函数,从而帮助agent学习到最优的...

Global site tag (gtag.js) - Google Analytics