zoukankan      html  css  js  c++  java
  • 394. 硬币排成线

    394. 硬币排成线

    中文English

    有 n 个硬币排成一条线。两个参赛者轮流从右边依次拿走 1 或 2 个硬币,直到没有硬币为止。拿到最后一枚硬币的人获胜。

    请判定 先手玩家 必胜还是必败?

    若必胜, 返回 true, 否则返回 false.

    样例

    样例 1:

    输入: 1
    输出: true
    

    样例 2:

    输入: 4
    输出: true
    解释: 
    先手玩家第一轮拿走一个硬币, 此时还剩三个.
    这时无论后手玩家拿一个还是两个, 下一次先手玩家都可以把剩下的硬币拿完.
    

    挑战

    O(1) 时间复杂度且O(1) 存储。

    输入测试数据 (每行一个参数)如何理解测试数据?

     博弈型动态规划:

    博弈动态规划通常从第一步分析,而不是最后一步
    因为局面越来越简单,石子数越来越少

    如果取1个或2个石子后,能让剩下的局面先手必败,则当前先手必胜
    如果不管怎么走,剩下的局面都是先手必胜,则当前先手必败

    必胜:在当前的局面走出一步,让对手无路可逃
    必败:自己无路可逃

    要求面对N个石子,是否先手必胜
    需要知道面对N-1个石子和N-2个石子,是否先手必胜
    子问题:
    设f[i]表示面对i个石子,是否先手必胜
    f[i] = True/Fasle

    只要有一个必败就必胜(保证后手一个必败就可以)
    f[i] = f[i-1] == False or f[i-2] == False

    初始条件:
    f[0] = False 面对0个,先手肯定必败
    f[1] = f[2] = True 面对1或者2个石子,先手肯定必胜

    计算顺序:
    f[0] ,f[1],f[2]...f[n]
    如果f[n] = True 则先手必胜,否则先手必败
    时间复杂度O(n)

    class Solution:
        """
        @param n: An integer
        @return: A boolean which equals to true if the first player will win
        """
        def firstWillWin(self, n):
            # write your code here
            #动态规划思想
            dp = [False for _ in range(n + 1)]
            
            for i in range(1,n + 1):
                if i == 1 or i == 2:
                    dp[i] = True 
                    continue
                
                dp[i] = dp[i - 1] == False or dp[i - 2] == False
            
            return dp[n]
  • 相关阅读:
    【maven】之打包war依赖子项目jar
    ~~运算符
    ~运算符
    Vuex文档
    vue-cli文档
    express文档
    vue-router 2文档
    Swiper文档
    基于React服务器端渲染的博客系统
    react.JS
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/13090687.html
Copyright © 2011-2022 走看看