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.
题意:
两个人轮流取数组里的数字,只能从两端取,问是否能使得第一个人取的数总和不小于第二个人的,保证两个人都按最大的方案取。
思路:
动态规划。但是想半天想不出。设置二维数组sum1[i][j]表示i-j的和,包括i和j,dp[i][j]表示i-j取的最大的和。两个人轮流使用dp[i][j],比如dp[0][n-1]表示第一个人的,dp[i][n-1],dp[0][n-2]表示第二个人的。那么可以得到dp[i][j]=max(sum1[i][j]-dp[i+1][j],sum1[i][j]-dp[i][j-1])。最后只需要求出2*dp[0][n-1]>=sum(nums)即可。
需要注意的是dp[i][i]在初始时需要赋值为nums[i],并且在进行动态规划时,需要注意下标怎么变化,需要不断扩大范围,i从n-1到0,j从i+1到n-1.
代码:
class Solution:
def PredictTheWinner(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
total=sum(nums)
sum1=[[0 for i in range(len(nums))] for i in range(len(nums))]
dp=[[0 for i in range(len(nums))] for i in range(len(nums))]
for i in range(len(nums)):
dp[i][i]=nums[i]
for i in range(len(nums)):
for j in range(i+1,len(nums)):
sum1[i][j]=sum(nums[:j+1])-sum(nums[:i])
for i in range(len(nums)-2,-1,-1):
for j in range(i+1,len(nums)):
dp[i][j]=max(sum1[i][j]-dp[i+1][j],sum1[i][j]-dp[i][j-1])
if 2*dp[0][len(nums)-1]>=total:
return True
else:
return False