您的位置:首页 > 编程语言 > Java开发

纸牌博弈(动态规划java)

2017-10-27 16:30 211 查看
1、牛客网题目:


题目描述

有一个整型数组A,代表数值不同的纸牌排成一条线。玩家a和玩家b依次拿走每张纸牌,规定玩家a先拿,玩家B后拿,但是每个玩家每次只能拿走最左或最右的纸牌,玩家a和玩家b都绝顶聪明,他们总会采用最优策略。请返回最后获胜者的分数。

给定纸牌序列A及序列的大小n,请返回最后分数较高者得分数(相同则返回任意一个分数)。保证A中的元素均小于等于1000。且A的大小小于等于300。
测试样例:
[1,2,100,4],4

返回:101


2、code实现:参考了其他人的代码,自己又总结了一遍思想,感觉这个思想还是有点绕的

package schooloffer;

/**
* Created by caoxiaohong on 17/10/27.
* 有一个整型数组A,代表数值不同的纸牌排成一条线。....
* 动态规划
* 规定:
* (1)玩家a先拿,玩家B后拿.
* (2)每个玩家每次只能拿走最左或最右的纸牌.
* (3)玩家a和玩家b都绝顶聪明,他们总会采用最优策略。
* (4)请返回最后获胜者的分数
*
* 关于本题一个比较重要的思想:就是code中的第二层for循环里面的a[i][j]和b[i][j]的表达式是怎么得来的.解释如下:
* (11)对于选手a,在纸牌范围为[i...j]时,a[i][j]如何表达?
*    如果选择A[i],则依赖于选手b的下一次在纸牌范围为[i+1...j]时,a尽量获取本次取牌的最大值且保证b获取下次取牌的尽量较小的值;
*    如果选择A[j],则依赖于选手b的下一次在纸牌范围为[i...j-1]时,a尽量获取本次取牌的最大值且保证b获取下次取牌的尽量较小的值.
* (22)对于选手b,在纸牌范围为[i...j]时,b[i][j]如何表达?
*    作为后手,因为a是足够聪明的,所以b的取值已经被a限制了,b只能取a在[i...j]取完牌后,在a下次取牌前,取出a可以在下次取牌时两种选择状态中值最小的那个,因为a要获得较大的那个嘛
*    如果a选择了A[i],那么b只能在纸牌范围为[i+1...j]中选择;
*    如果a选择了A[j],那么b只能在纸牌范围为[i...j-1]中选择.
*/
public class Cards {
public int cardGame(int[] A, int n) {
// write code here
int[][] a=new int

;//玩家a , a[i][j]表示:纸牌为[i...j]时,玩家a可以获得的最多分数
int[][] b=new int

;//玩家b , b[i][j]表示:纸牌为[i...j]时,玩家b可以获得的最多分数

for(int j=0;j<n;j++){
a[j][j]=A[j];
for(int i=j-1;i>=0;i--){
a[i][j]=Math.max(A[i]+b[i+1][j],A[j]+b[i][j-1]);//来源于(11)说明
b[i][j]=Math.min(a[i+1][j],a[i][j-1]);//来源于(22)说明
}
}
return Math.max(a[0][n-1],b[0][n-1]);
}

//test <code></code>
public static void main(String[] args) {
Cards t=new Cards();
int[] a={1,2,100,4};
System.out.println(t.cardGame(a,4));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: