LeetCode 1406. 石子游戏 III (极小化极大、一维线性DP、博弈)

石子游戏 III

  • 状态: O ( d p [ i ] ) O(dp[i]) O(dp[i]) 表示从下标 i i i开始到结束当前先手的人能取到的最大值。
  • DP方程: d p [ i ] = m a x ( d p [ i ] , s [ i , i + k − 1 ] + s [ i + k , n − 1 ] − d p [ i + k ] ) dp[i] = max(dp[i],s[i,i+k-1] + s[i+k,n-1]-dp[i+k] ) dp[i]=max(dp[i],s[i,i+k1]+s[i+k,n1]dp[i+k])
    极其重要的一点思想,因为对于当前先手的人的下一个人也会遇到和先手的人相同的选择策略,所以当先手的人选择了k个石子堆后,对于后面剩余的石子堆他还能获得的石子堆的个数其实是后面的石子总数减去后手的人能获得的最大值。
  • 注意点:注意石子堆对应的分数有正有负,所以 d p [ ] dp[] dp[]初始化为无穷小。其次又因为每次不能一个都不选,所以要多一个 d p [ n ] = 0 dp[n] =0 dp[n]=0的边界。
class Solution {
    
    
public:
    string stoneGameIII(vector<int>& a) {
    
    
        int n = a.size();
        vector<int> dp(n+1,-1e9), suf(n+1,0);
        for(int i=n-1;i>=0;i--){
    
    
            suf[i] = suf[i+1]+a[i];
        }
        dp[n] = 0; //边界
        for(int i=n-1;i>=0;i--){
    
    
            for(int k=1;k<=3;k++){
    
    
                if(i+k<=n) dp[i] = max(dp[i],suf[i]-dp[i+k]);
            }
        }
        if(suf[0]-dp[0]<dp[0]){
    
    
            return "Alice";
        }else if(suf[0]-dp[0]>dp[0]){
    
    
            return "Bob";
        }else{
    
    
            return "Tie";
        }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/108410291
今日推荐