zoukankan      html  css  js  c++  java
  • 486. Predict the Winner

    问题

    给定一系列非负的整数,两个玩家轮流从头部或尾部取数,两人都以最优策略玩,问先取数的玩家是否获胜。

    Input: [1, 5, 2]
    Output: False

    思路

    这道题跟877. Stone Game一样,只不过没有了几个先验条件,这道题是Stone Game更一般的场景,这道题的代码可以直接过Stone Game。

    上次(Stone Game)的dp解法中用双方博弈的思路,有两条公式。其实直接一条公式就可以了。

    如果dp[i][j]表示自己取石头,能够获得的比对方多的价值。

    那dp[i+1][j]和dp[i][j+1]就是对方取石头,能够获得比自己多的价值。

    dp公式为:(dp[i][j] = max(nums[i] - dp[i+1][j], nums[j] - dp[i][j-1]))

    dp值取决于左方值和下方值,dp矩阵的遍历有几种方式,可以按对角线遍历;也可以按行(先遍历完一行),从下往上遍历;还可以按列(先遍历完一列)。

    三种遍历都可以优化成一维数组,如下图所示。

    (1)按对角线遍历,遍历完一个对角线,再往右上角的另一个对角线遍历,可以覆盖前一个对角线

    (2)按行遍历,遍历完一行,再向上一行遍历,可以覆盖下一行

    (3)按列遍历,遍历完一列,再向右一列遍历,可以覆盖前一列

    时间复杂度O(n^2),空间复杂度O(n)

    代码

    Stone Game里我使用的是按对角线遍历的代码,这里我用的是按行遍历的代码。

    class Solution(object):
        def PredictTheWinner(self, nums):
            """
            :type nums: List[int]
            :rtype: bool
            """
            dp = [0 for _ in range(len(nums))]
            for i in range(len(nums)-1)[::-1]:
                for j in range(i+1, len(nums)):
                    dp[j] = max(nums[i] - dp[j], nums[j] - dp[j-1])
            return dp[len(nums)-1]>=0
            
    

    类似题目

    877. Stone Game

  • 相关阅读:
    几个常见的在线评测系统,及我的点评
    信息学奥赛培训教材推荐
    致,青春
    文明小博客,管理员及网址列表
    NOIP2013,复赛及同步赛,报名及比赛,专题页面
    浅谈浏览器兼容性问题-(1)产生、看待与思考
    前端经典笔试题(腾讯前端,三栏布局)
    浅谈web语义化
    浅谈表现与数据分离
    浅谈w3c标准
  • 原文地址:https://www.cnblogs.com/liaohuiqiang/p/9770457.html
Copyright © 2011-2022 走看看