紙牌博弈問題

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]);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章