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; } };