思路:两个状态为开始取石子的索引i和可以取走的堆数M,我们最后要返回的结果为dp[0][1],所以我们的遍历顺序为从后往前,假设最后一次从i开始取石子,可以取走全部石子,则dp[i][M]等于剩余的所以石子数量和,如果不能全部取走,则dp[i][M]为使得下一个人取得最小的石子数量和。
class Solution {
public:
int stoneGameII(vector<int>& piles) {
int n=piles.size(),sum=0;
vector<vector<int>>dp(n,vector<int>(n+1,0));
for(int i=n-1;i>=0;i--){
sum+=piles[i];
for(int M=1;M<=n;M++){
//可以取走全部石头
if(i+2*M>=n){
dp[i][M]=sum;
}else{
//本轮取走的堆数要保证下轮对手取走的堆数最小
for(int x=1;x<=2*M;x++){
dp[i][M]=max(dp[i][M],sum-dp[i+x][max(x,M)]);
}
}
}
}
return dp[0][1];
}
};