leetcode486. 预测赢家

dp考虑先后手的区别

def PredictTheWinner(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        #定义dp[i][j][0] 是1先手在[i,j]区间可以得到的最大分数
        #定义dp[i][j][1] 是2后手在[i,j]区间可以得到的最大分数
        #dp[i][i][0] = nums[i]
        #先手选左边  dp[i][j][0] = dp[i+1][j][1] + nums[i] , 后手剩下 dp[i][j][1] = dp[i+1][j][0]
        #先手选右边  dp[i][j][0] = dp[i][j-1][1] + nums[j] , 后手剩下 dp[i][j][1] = dp[i][j-1][0]
        #解释上面的,先手选了左边,加上左边的元素,做完选择之后变成了后手所以是加上dp[i+1][j][1]选择后的后手
        #           先手选了左边,后手此时变成了先手,还剩下先手选择完的piles[i+1...j]变成了dp[i+1][j][0]
        n = len(nums)
        dp = [[[0,0] for i in range(n)] for j in range(n)]
        for i in range(n):
            dp[i][i][0] = nums[i]
        
        for i in range(n-2,-1,-1):
            for j in range(i+1,n):
                left = dp[i+1][j][1] + nums[i] 
                right = dp[i][j-1][1] + nums[j]
                if left > right:                                 #倒着推先手会选择更大的数
                    dp[i][j][0] = dp[i+1][j][1] + nums[i] 
                    dp[i][j][1] = dp[i+1][j][0]
                else:
                    dp[i][j][0] = dp[i][j-1][1] + nums[j]
                    dp[i][j][1] = dp[i][j-1][0]
        i,j = dp[0][n-1]
        return i-j >= 0

dp不考虑先后手的区别
甲乙比赛,甲先手面对区间[i…j]时,dp[i][j]表示甲对乙的净胜分。
最终求的就是,甲先手面对区间[0…n-1]时,甲对乙的净胜分dp[0][n-1]是否>=0。
甲先手面对区间[i…j]时,
如果甲拿nums[i],那么变成乙先手面对区间[i+1…j],这段区间内乙对甲的净胜分为dp[i+1][j];那么甲对乙的净胜分就应该是nums[i] - dp[i+1][j]。
如果甲拿nums[j],同理可得甲对乙的净胜分为是nums[j] - dp[i][j-1]。
以上两种情况二者取大即可。

def stoneGame(self, piles):
        """
        :type piles: List[int]
        :rtype: bool
        """
        #定义dp为区间[i,j]某个人先手能取得的净胜分数
        n = len(piles)
        dp = [[0]*n for i in range(n)]
        for i,pile in enumerate(piles):
            dp[i][i] = pile
        for i in range(n-2,-1,-1):
            for j in range(i+1,n):
                dp[i][j] = max(piles[i] - dp[i+1][j],piles[j]-dp[i][j-1])
        return dp[0][n-1]>=0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值