LeetCode 486. Predict the Winner

Solution 写的很好,怎么一步步到dp的 https://leetcode.com/problems/predict-the-winner/solution/

 

dp[i][j] 当前玩家从下标i~j的数组,能取得的比另一个玩家多的分数

base case dp[i][i]=nums[i]

每次当前玩家只能取头或者尾,如果取头,dp[i][j] = nums[i] - dp[i+1][j],因为下一轮就是另一个玩家取,他能比当前玩家多 dp[i+1][j],所以当前玩家取头的话,能比另一个玩家多 nums[i] - dp[i+1][j]

同理,如果取尾,dp[i][j] = nums[j] - dp[i][j-1]

dp[i][j] 选两个中较大的

class Solution {
public:
    bool PredictTheWinner(vector<int>& nums) {
        int n=nums.size();
        // dp[i][j] how much more scores that the first-in-action player will get from i to j than the second player
        vector<vector<int>> dp(n, vector<int>(n,0));
        for (int i=0;i<n;++i) dp[i][i]=nums[i];
        for (int i=n-2;i>=0;--i){
            for (int j=i+1;j<n;++j){
                dp[i][j] = max(nums[i]-dp[i+1][j], nums[j]-dp[i][j-1]);
            }
        }
        return dp[0][n-1]>=0;
    }
};

 

由于更新dp只依据下一行和当前行,因此可以把空间复杂度降到O(n)

class Solution {
public:
    bool PredictTheWinner(vector<int>& nums) {
        int n=nums.size();
        vector<int> dp(n,0);
        for (int i=n-1;i>=0;--i){
            dp[i] = nums[i];
            for (int j=i+1;j<n;++j){
                dp[j] = max(nums[i]-dp[j], nums[j]-dp[j-1]);
            }
        }
        return dp[n-1]>=0;
    }
};

 

https://leetcode.com/problems/predict-the-winner/discuss/96828/JAVA-9-lines-DP-solution-easy-to-understand-with-improvement-to-O(N)-space-complexity.

posted @ 2018-11-09 00:14  約束の空  阅读(117)  评论(0)    收藏  举报