package July;
/**
* DP
* 有一个整型数组A,代表数值不同的纸牌排成一条线。
* 玩家a和玩家b依次拿走每张纸牌,规定玩家a先拿,玩家B后拿,
* 但是每个玩家每次只能拿走最左或最右的纸牌,玩家a和玩家b都绝顶聪明,他们总会采用最优策略。
* 请返回最后获胜者的分数。
*
给定纸牌序列A及序列的大小n,请返回最后分数较高者得分数(相同则返回任意一个分数)。
保证A中的元素均小于等于1000。且A的大小小于等于300。
* @date 2017年7月24日 下午1:55:06
* @description
*
*/
public class Poker {
public int cardGame(int[] A, int n) {
int F[][] = new int[n][n]; //F[i][j]表示布局为i~j时先手的最大收益
int S[][] = new int[n][n]; //S[i][j]表示布局为i~j时后手的最大收益
//初始化 布局为i~i时,先手的收益为A[i]
for (int i = 0; i < F.length; i++) {
F[i][i] = A[i];
}
//F[i][j] = max {A[i]+S[i+1][j], A[j]+ S[i][j-1]}
//S[i][j] = min {F[i+1][j], F[i][j-1]}
//两重循环,算F|S[i][j]
//已知F|S[i][i] 可以作为切入点
for (int i = S.length -1; i >= 0; i--) {
for (int j = i+ 1; j < S.length; j++) {
F[i][j] = Math.max(A[i]+S[i+1][j], A[j]+ S[i][j-1]);
S[i][j] = Math.min(F[i+1][j],F[i][j-1]);
}
}
return Math.max(F[0][n -1], S[0][n -1]);
}
}
纸牌博弈问题
最新推荐文章于 2023-03-05 19:44:57 发布