486. Predict the Winner

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. 1 <= length of the array <= 20.
  2. Any scores in the given array are non-negative integers and will not exceed 10,000,000.
  3. 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
            
        
        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值