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]);
}
}
紙牌博弈問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.