zoukankan      html  css  js  c++  java
  • Coins in a Line II

    here are n coins with different value in a line. Two players take turns to take one or two coins from left side until there are no more coins left. The player who take the coins with the most value wins.

    Could you please decide the first player will win or lose?

    Given values array A = [1,2,2], return true.

    Given A = [1,2,4], return false.

    Coins in a Line 三部曲的第二部,也是道博弈类的DP。这类问题每次定义一个人的状态。比如这题我们定义f[i]为还剩i枚硬币时先手取硬币的人获得的最大价值。这里从左朝右走,所以还剩i枚是从右往左走的。我们求的最终状态是还剩n枚硬币时先手的状态(也就是真正对应第一个取硬币的人)。注意这里定义状态里的先手并不一定是我们题意所说的游戏开始的先手,题目中的先手是f[n]时的先手,而在f[i]时的先手仅仅是在还剩i枚硬币时第一个取硬币的人,可以是player A, 也可以是player B。

    考虑转移方程,还剩i枚硬币时的状态,可以通过从左边取1枚或者2枚到达f[i-1],f[i-2]。 当然这个取硬币的人是f[i]中的先手,f[i-1],f[i-2]中的后手。所以转换方程是

    f[i] = sum[i] - min(f[i-1],f[i-2])

    初始化状态,当还剩0枚硬币时,先手获得的最大价值是0,还剩1枚时,f[1] = values[-1], 还剩2枚时,f[2] = values[-1]+values[-2].

    最后取值是f[n]*2 > sum[n]

    这题要相当注意初始化的处理,代码如下:

    class Solution:
        # @param values: a list of integers
        # @return: a boolean which equals to True if the first player will win
        def firstWillWin(self, values):
            if not values:
                return 0
            if len(values) < 2:
                return True
            dp = [0] * (len(values) + 1)  #while the i coins left, the first player's                             #most value, i is from right to left
            dp[1] = values[-1]
            dp[2] = values[-1] + values[-2]
            sums = [values[-1]]
            for i in xrange(len(values) - 2, -1, -1): #from right to left 
                sums.append(sums[-1] + values[i])
            for i in xrange(3,len(values) + 1):
                dp[i] = sums[i-1] - min(dp[i-2],dp[i-1])
                    
            return dp[len(values)]*2 > sums[len(values)-1]
        

    这题需要用到求和来做推演,所以最好的方式是预先求出来,prefixsum的形式,空间和时间复杂度都是O(n).

  • 相关阅读:
    Weblogic任意文件上传漏洞(CVE-2018-2894)复现
    Angular动态创建组件之Portals
    nodejs 开发企业微信第三方应用入门教程
    系列文章|OKR与敏捷(三):赋予团队自主权
    Angular开发技巧
    系列文章|OKR与敏捷(二):实现全栈敏捷
    系列文章|OKR与敏捷(一):瀑布式目标与敏捷的冲突
    OKR与Scrum如何强强联手
    Service Worker
    RxJS 实现摩斯密码(Morse) 【内附脑图】
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5613307.html
Copyright © 2011-2022 走看看