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.
Example 1:
Input: [1, 5, 2]
Output: False
Explanation: Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return False.
Example 2:
Input: [1, 5, 233, 7] Output: True Explanation: Player 1 first chooses 1. Then player 2 have to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233.
Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win.
Note:
- 1 <= length of the array <= 20.
- Any scores in the given array are non-negative integers and will not exceed 10,000,000.
- If the scores of both players are equal, then player 1 is still the winner.
题目大意:
给定一系列非负整数的分数。玩家1从数组的两端选择其中一个数字,然后是玩家2,然后是玩家1,以此类推。每一次玩家选择一个数字,这个数字将不会为下一个玩家提供。这样一直持续到所有的分数都被选中。得分最高的球员获胜。
给定一组分数,预测玩家1是否获胜。你可以假设每个球员都能发挥最大的得分。
给定一组分数,预测玩家1是否获胜。你可以假设每个球员都能发挥最大的得分。
分析:
要求求玩家1的最大分数,我们假设一个二维的数组dp,dp[i][j]代表是在从第i到j位先选的那位玩家会比后选的那位玩家多出来的分数,然后我们考虑如何更新dp数组
,再回到这个问题考虑一下,每位玩家要么从左边选择,要么从右边选择,假设他们现在在第i到j位里面选数字,现在刚好轮到A,如果A选择了位置i,A就获得了nums【i】
的分数,然后B只能从位置i+1到位置j中选择了,根据我们dp的定义,dp[i+1][j]代表的是先选的那位玩家可以比后选的那位玩家多出来的分数,所以在位置i+1到j中获得
分数时,玩家B将比玩家A多出dp[i+1][j]的分数,所以玩家A一旦选择了位置i的值,那么他的最终获得的分数情况j将会比玩家B多出nums[i]-dp[i+1][j]的分数,同理,玩家A
选择了j位置,那么玩家A将会比玩家B多出nums[j]-dp[i][j-1]的分数,
由此可得到递推关系:dp[i][j]=Math.max(nums[i]-dp[i+1[j],nums[j]-dp[i][j-1]);
public boolean PredictTheWinner(int[] nums) {
int n=nums.length;
int[][] dp=new int[n][n];
for(int i=0;i<n;i++) {
dp[i][i]=nums[i]; //因为dp[i][i]刚好表示i点出的值
}
for(int len=1;len<n;len++) { //len 代表二维数组当前要进行操作的位置离对角线的距离。
for(int i=0;i<n-len;i++) {
int j=i+len;
dp[i][j]=Math.max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]);
}
}
return dp[0][n-1]>=0;
}
参考资料:https://discuss.leetcode.com/topic/76830/java-9-lines-dp-solution-easy-to-understand-with-improvement-to-o-n-space-complexity