Description
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the next player. This continues until all the scores have been chosen. The player with the maximum score wins.
Given an array of scores, predict whether player 1 is the winner. You can assume each player plays to maximize his score.
Thinking
玩家1与玩家2先后轮流从队列nums头或尾取数字,最后数字总和最大的为赢家。用动态规划解决即可。
将问题从大往小逐渐拆分,设队列长度为len,创建一个二维数组dp[len][len],dp[begin][end]表示在nums[begin]到nums[end]之间范围内进行游戏,玩家1与玩家2之间的分数差值。当begin和end相等的时候,dp[begin][end]的值即为nums[begin](或者nums[end]),如果begin和end不等,那么如果取begin,结果为nums[begin] – dp[begin+1][end]; 如果取end,结果为nums[end] – dp[begin][end-1],dp[begin][end]取它俩中较大的一个,因此得到递归式:max(nums[beg] - partition(beg + 1, end), nums[end] - partition(beg, end - 1))。
为了实现动态规划,减少重复计算,需要用这个二维数组存储每个小问题的计算结果。
开始时,我们只知道对角线上的值恰好与Nums数列中的值一一对应。接下来要做的就是讲二维数组dp[len][len]的上三角填满。我们先从右下角开始,利用已知的数据求出小区间dp[b[][e]的值。
Solution
class Solution {
public:
bool PredictTheWinner(vector<int>& nums) {
int len = nums.size();
if(len < 0) return false;
int dp[len][len];
for(int i = 0; i < len; i++){
dp[i][i] = nums[i];
}
for(int b = len - 2; b >= 0; b--){
for(int e = b + 1; e < len; e++){
if(nums[b] - dp[b + 1][e] >= nums[e] - dp[b][e - 1]) dp[b][e] = nums[b] - dp[b + 1][e];
else dp[b][e] = nums[e] - dp[b][e - 1];
}
}
return dp[0][len - 1] >=0;
}
};