【Leetcode】1690. Stone Game VII

記錄演算法發表於2020-12-14

題目地址:

https://leetcode.com/problems/stone-game-vii/

給定一個長 n n n陣列 A A A,代表若干石子對應的得分。兩個人甲和乙輪流從最左和最右拿石子,拿一次石子的得分是剩餘所有石子分數之和。問甲比乙贏的最大分差是多少。假設兩人都是以對自己最優的方式拿石子的(這裡的最優就是使得自己得分最高)。

思路是動態規劃。設 f [ i ] [ j ] f[i][j] f[i][j]是當石子只剩下 A [ i : j ] A[i:j] A[i:j]時先手能贏的最大分差。則先手可能拿最左的石頭,也可能拿最右的石頭,所以有: f [ i ] [ j ] = max ⁡ { ∑ A [ i + 1 : j ] − f [ i + 1 ] [ j ] , ∑ A [ i : j − 1 ] − f [ i ] [ j − 1 ] } f[i][j]=\max\{\sum A[i+1:j]-f[i+1][j],\sum A[i:j-1]-f[i][j-1]\} f[i][j]=max{A[i+1:j]f[i+1][j],A[i:j1]f[i][j1]}初始條件就是長度為 1 1 1的情形, f f f 0 0 0。程式碼如下:

public class Solution {
    public int stoneGameVII(int[] stones) {
        int n = stones.length;
        int[] preSum = new int[n + 1];
        for (int i = 0; i < n; i++) {
            preSum[i + 1] = preSum[i] + stones[i];
        }
        
        int[][] dp = new int[n][n];
        for (int len = 2; len <= n; len++) {
            for (int l = 0; l + len - 1 < n; l++) {
                int r = l + len - 1;
                dp[l][r] = Math.max(preSum[r + 1] - preSum[l + 1] - dp[l + 1][r], preSum[r] - preSum[l] - dp[l][r - 1]);
            }
        }
        
        return dp[0][n - 1];
    }
}

時空複雜度 O ( n 2 ) O(n^2) O(n2)

相關文章