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);
}
};
东北日出西边雨 道是无情却有情

浙公网安备 33010602011771号