because we always need to query the interval sum. So, we make this operation to become O(1) using prefixSum.
[1, 2, 3, 4]
^ ^
i i+1
if we pick up the left stone, dp[i + 1][j], if we pick up the right stone, dp[i][j - 1].
as both players would maximize the difference. so.
class Solution {
public:
int stoneGameVII(vector<int>& stones) {
int n = stones.size();
vector<vector<int>> dp(n, vector<int>(n, 0));
vector<int> prefixSum(n + 1, 0);
prefixSum[1] = stones[0];
for(int i = 2; i <= n; i++){
prefixSum[i] = prefixSum[i - 1] + stones[i - 1];
}
for(int i = n - 1; i >= 0; i--){
for(int j = i + 1; j < n; j++){
dp[i][j] = max(prefixSum[j + 1] - prefixSum[i + 1] - dp[i + 1][j],
prefixSum[j] - prefixSum[i] - dp[i][j - 1]);
}
}
return dp[0][n - 1];
}
};