leedcode-1563. 石子游戏 V

 

 思路一:(区间dp)

dp[i][j] 表示合并区间 i ~ j 所能获得的最大收益

class Solution {
public:

    int a[505];
    int dp[505][505];
    int stoneGameV(vector<int>& stoneValue) {
        int len = stoneValue.size();

        for(int i = 1; i <= len; i++) {
            a[i] = stoneValue[i-1];
            a[i] += a[i-1];
        }

        for(int ls = 2; ls <= len; ls++){ // 长度
            for(int i = 1; i <= len; i++) { // 左端
                int j = i + ls - 1; //右端
                if (j > len) break;
                for(int k = i; k < j; k++){
                    int sum_l = a[k] - a[i-1];
                    int sum_r = a[j] - a[k];
                    if (sum_l > sum_r) dp[i][j] = max(dp[i][j], dp[k+1][j] + sum_r);
                    else if (sum_l < sum_r) dp[i][j] = max(dp[i][j], dp[i][k] + sum_l);
                    else dp[i][j] = max(dp[i][j], max(dp[i][k]+sum_l, dp[k+1][j]+sum_r));
                }
            }
        }
        return dp[1][len];
    }
};

  

思路二:(记忆化搜索)

class Solution {
public:
    int sum[505];
    int dp[505][505];
    int dfs(int l, int r){
        if (l >= r) return 0;
        if (dp[l][r]) return dp[l][r];

        int ans = 0;
        for(int i = l; i < r; i++){
            int s1 = sum[i]-sum[l-1];
            int s2 = sum[r]-sum[i];
            if(s1 < s2) ans = max(ans, s1 + dfs(l, i));
            else if (s1 > s2) ans = max(ans, s2 + dfs(i+1, r));
            else ans = max(ans, max(dfs(l, i), dfs(i+1, r))+s1);
        }
        return dp[l][r] = ans;
    }

    int stoneGameV(vector<int>& stoneValue) {
        sum[1] = stoneValue[0];
        for(int i = 1; i < stoneValue.size(); i++) {
            sum[i+1] = sum[i] + stoneValue[i];
        }   
        int len = stoneValue.size();

        return dfs(1, len);
    }
};

  

posted @ 2022-06-08 16:17  楼主好菜啊  阅读(21)  评论(0编辑  收藏  举报