1. 程式人生 > 實用技巧 >5627. 石子游戲 VII DP

5627. 石子游戲 VII DP

石子游戲中,愛麗絲和鮑勃輪流進行自己的回合,愛麗絲先開始 。

有 n 塊石子排成一排。每個玩家的回合中,可以從行中 移除 最左邊的石頭或最右邊的石頭,並獲得與該行中剩餘石頭值之 和 相等的得分。當沒有石頭可移除時,得分較高者獲勝。

鮑勃發現他總是輸掉遊戲(可憐的鮑勃,他總是輸),所以他決定盡力 減小得分的差值 。愛麗絲的目標是最大限度地 擴大得分的差值 。

給你一個整數陣列stones ,其中 stones[i] 表示 從左邊開始 的第 i 個石頭的值,如果愛麗絲和鮑勃都 發揮出最佳水平 ,請返回他們 得分的差值 。

示例 1:

輸入:stones = [5,3,1,4,2]
輸出:6
解釋:

  • 愛麗絲移除 2 ,得分 5 + 3 + 1 + 4 = 13 。遊戲情況:愛麗絲 = 13 ,鮑勃 = 0 ,石子 = [5,3,1,4] 。
  • 鮑勃移除 5 ,得分 3 + 1 + 4 = 8 。遊戲情況:愛麗絲 = 13 ,鮑勃 = 8 ,石子 = [3,1,4] 。
  • 愛麗絲移除 3 ,得分 1 + 4 = 5 。遊戲情況:愛麗絲 = 18 ,鮑勃 = 8 ,石子 = [1,4] 。
  • 鮑勃移除 1 ,得分 4 。遊戲情況:愛麗絲 = 18 ,鮑勃 = 12 ,石子 = [4] 。
  • 愛麗絲移除 4 ,得分 0 。遊戲情況:愛麗絲 = 18 ,鮑勃 = 12 ,石子 = [] 。
    得分的差值 18 - 12 = 6 。
    示例 2:

輸入:stones = [7,90,5,1,100,10,10,2]
輸出:122

提示:

n == stones.length
2 <= n <= 1000
1 <= stones[i] <= 1000

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/stone-game-vii
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

class Solution {
public:
    int stoneGameVII(vector<int>& stones) {
        int n = stones.size();
        int dp[n][n];  // 表示從i到j,A和B的最大差值
        
        int pre[n + 1]; // 字首和陣列
        for (int i = 0; i < n; i++) {
            pre[i + 1] = pre[i] + stones[i];
        }

        for (int i = 0; i < n; i++) {
            dp[i][i] = 0; // 當只有一個石子時,AB差值為0
        }

        for (int len = 2; len <= n; len++) {
            for (int i = 0; i + len - 1 < n; i++) {
                int j = i + len - 1;
                // [0, j] - [0, i] = (i, j]     dp[i + 1][j]
                // [0, j - 1] - [0, i - 1] = [i, j)     dp[i][j - 1]
                dp[i][j] = max(pre[j + 1] - pre[i + 1] - dp[i + 1][j], pre[j] - pre[i] - dp[i][j - 1]);
            }
        }

        return dp[0][n - 1];
    }
};