464我能赢吗

题目:在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和达到 100 的玩家,即为胜者。如果我们将游戏规则改为 “玩家不能重复使用整数” 呢?例如,两个玩家可以轮流从公共整数池中抽取从 1 到 15 的整数(不放回),直到累计整数和 >= 100。给定一个整数 maxChoosableInteger (整数池中可选择的最大数)和另一个整数 desiredTotal(累计和),判断先出手的玩家是否能稳赢(假设两位玩家游戏时都表现最佳)?你可以假设 maxChoosableInteger 不会大于 20, desiredTotal 不会大于 300。

来源:https://leetcode-cn.com/problems/can-i-win/

法一:参考https://leetcode.com/problems/can-i-win/discuss/439435/Python-Minimax-Simple

思路:代码的写法极为精妙,这个题由于不易写出状态转移方程,故用备忘录的方法,python中的字典key不能为list,只能是tuple,这个题备忘录的键是剩余的元素组成的tuple,而值是输赢的两种状态,

class Solution(object):
    def canIWin(self, maxChoosableInteger, desiredTotal):
        # 先特判,两家都不能赢时,直接返回False,即总和达不到目标值
        if maxChoosableInteger * (maxChoosableInteger + 1) / 2 < desiredTotal:
            return False
        # 如果非正,直接返回True
        if desiredTotal <= 0:
            return True
        bool_array = [i for i in range(1, maxChoosableInteger + 1)]
        print(bool_array)
        cache = {}
        def minimax(desiredTotal, visited):
            # 如果备忘录中存在该key,则直接返回
            if tuple(visited) in cache:
                return cache[tuple(visited)]
            # 如果小于等于0,说明达到目标值了,结束回溯
            if desiredTotal <= 0:
                print(visited,desiredTotal)
                return False
            for i in range(len(visited)):
                temp = visited[i]
                # 数组中除i之外的元素
                newV = visited[:i] + visited[i + 1:]
                # 如果返回的是False,表示对与visited,先拿的有必赢的方法,此时则以visited为key,值为True,
                # 如果返回的是True,表示如果此时先手拿掉数字temp,则后手可以赢,则不再遍历此时的temp,遍历下一个temp
                if not minimax(desiredTotal - temp, newV):
                    # 如果走到这一步,说明minimax(desiredTotal - temp, newV)为False,也就是说如果此时某一方在visited中
                    # 取数temp,则他必定赢,所以把visited记成True,表示一定能赢
                    cache[tuple(visited)] = True
                    # 这个return True是因为走到这一步,说明已经在visited中找到一个数可以达到目标值了,此时便结束这个函数,
                    # 因为此时已经可以保证现在拿数的这个人赢了,没必要继续遍历了,
                    # 而这一步如果可以达到目标值的话,则上一步则达不到目标值,所以返回后不再记录
                    return True
            # 如果走到这一步,说明上面for循环内的if语句都是True,也就是说visited中拿掉任意一个temp后,
            # 接下来拿的人有必赢的方法,所以这里记为False,表示必输
            cache[tuple(visited)] = False
            # 如果在此时的visited中选数的人必输,那么上一步的人就必赢,所以返回False进行记录,
            return False
        print(minimax(desiredTotal, bool_array))
        print(cache)
        return minimax(desiredTotal, bool_array)
if  __name__ == ‘__main__‘:
    duixiang = Solution()
    # a = duixiang.canIWin(maxChoosableInteger = 4,desiredTotal = 7)
    a = duixiang.canIWin(maxChoosableInteger = 4,desiredTotal = 8)
    print(a)

ttt

原文地址:https://www.cnblogs.com/xxswkl/p/12268131.html

时间: 2024-10-18 01:44:00

464我能赢吗的相关文章

Leetcode 464.我能赢吗

我能赢吗 在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和达到 100 的玩家,即为胜者. 如果我们将游戏规则改为 "玩家不能重复使用整数" 呢? 例如,两个玩家可以轮流从公共整数池中抽取从 1 到 15 的整数(不放回),直到累计整数和 >= 100. 给定一个整数 maxChoosableInteger (整数池中可选择的最大数)和另一个整数 desiredTotal(累计和),判断先出手的玩

必胜技巧6

┏┯┓┏┯┓┏┯┓ ┠方┨┠法┨┠篇┨ ┗┷┛┗┷┛┗┷┛ 1.杀码 每期根据上期个位对应下面的数据杀个位3码,毒胆. 0=591 1=026 2=137 3=248 4=359 5=460 6=571 7=682 8=793 9=804 小技巧 SSC小技巧如跨1长时间不出,当开跨8或跨9时就可关注跨1了的!这是ssc出号规律!切记,,切记!! 还有豹子号码如跨0(豹子)长时间不出时,当开跨7或跨5时就可关注了的! 定毒胆妙法 时时彩"三星 定独胆妙法三则 人无完人,彩票中更是没有圣人,推荐几

leet

# 题名1 两数之和    2 两数相加    3 无重复字符的最长子串    4 寻找两个有序数组的中位数    5 最长回文子串    6 Z 字形变换    7 整数反转    8 字符串转换整数 (atoi)    9 回文数    10 正则表达式匹配    11 盛最多水的容器    12 整数转罗马数字    13 罗马数字转整数    14 最长公共前缀    15 三数之和    16 最接近的三数之和    17 电话号码的字母组合    18 四数之和    19 删除链表

状态压缩 - LeetCode #464 Can I Win

动态规划是一种top-down求解模式,关键在于分解和求解子问题,然后根据子问题的解不断向上递推,得出最终解 因此dp涉及到保存每个计算过的子问题的解,这样当遇到同样的子问题时就不用继续向下求解而直接可以得到结果.状态压缩就是用来保存子问题的解的,主要思想是把所有可能的状态(子问题)用一个数据结构(通常是整数)统一表示,再用map把每个状态和对应结果关联起来,这样每次求解子问题时先find一下,如果map里面已经有该状态的解就不用再求了:同样每次求解完一个状态的解后也要将其放入map中保存 状态

人生,别认输,因为没人希望你赢

别认输,因为没人希望你赢:别靠人,因为只有自己最可靠:别乞求,因为别人等着看笑话: 别落魄,因为一堆人在等着落井下石:别回首,因为看到的是未修复的裂痕:别离愁,因为只会才下眉头却上心头: 别低头,因为地上没有黄金只有石头:别强求,因为硬摘的果实,没有甜头.有些事情不要太计较,睁一只眼,闭一只眼,就会过去的. 别哭穷,因为没人会给你钱:别喊累,因为没人会帮你做:别想哭,因为大家并不在乎: 最难打开的是心门,最难走的路是心路,最难过的桥是心桥,最难调整的是心态.世界上最难干的工程是改造人的内心世界.

参与51CTO学院2周年庆-我和学院的故事 赢大奖

参与51CTO学院2周年庆-我和学院的故事 赢大奖 光阴飞逝,转眼间,51CTO学院就要二周岁啦! 在这两年里您从51CTO学院收获了什么? 在这两年里您的工作有了怎样的发展? 为了感谢一路陪伴学院的各位学员,特邀各位一起来回忆与学院的点点滴滴,并有丰厚大奖等着大家! 快来论坛帖子[奖]51CTO学院2周年庆-我和学院的故事,在帖子下方回复谈谈自己对学院周年的感想,可以说说当初来学院的初衷,也可以说说在学员群遇到的人和事,总之和学院有关的都可以. 只要参与就有奖品!大家快来积极参与吧! 帖子传送

BZOJ2463 谁能赢呢?

Description 小明和小红经常玩一个博弈游戏.给定一个n×n的棋盘,一个石头被放在棋盘的左上角.他们轮流移动石头.每一回合,选手只能把石头向上,下,左,右四个方向移动一格,并且要求移动到的格子之前不能被访问过.谁不能移动石头了就算输.假如小明先移动石头,而且两个选手都以最优策略走步,问最后谁能赢? Input 输入文件有多组数据. 输入第一行包含一个整数n,表示棋盘的规模. 当输入n为0时,表示输入结束. Output 对于每组数据,如果小明最后能赢,则输出”Alice”, 否则输出”B

和的时候一样,没有人可以赢我两次

天团!看你们的了!事实证明,四个战队的教练团合体之后,也不是不可战胜的我说过很多次了,的队伍选人太死板了!我早就说过机器人金克斯可以用,但全都喷我,现在他们太"今天要加油啊!!!! 果然教练分析的不错.必须- 第二把,上,讲道理,就算真的最后都输了,还是感动,终于不怂了!这次就是要跟刚正面!输赢我讲道理不管打谁--要赢兮夜就必须得站出来恭喜,两个字牛,瞬间以为大舅子和小狗的风格很像,不怂就是干,我狗皮肤?的伤害!厉害厉害世界毕竟还是赢了看到最后和米勒哭了真的心酸 这几年真的不容易 今年本土加油吧

王自如与老罗的辩论赛谁赢了?!

这场辩论是期待和看好的,看过了 就感觉是"刺激".由于看多了和和善善(一堆人和和气气的说话,都给对方留面子,有话绕着说那种谈话). 好了.转回这场"辩论". 事实上整场看下来,大多数都是老罗在表达观点. 并且老罗明显做了充分准备.而王自如就带了几篇纸."王自如怎么说得过自带PPT的相声演员呢?". 想想王自如的观点还真不多: 一是老罗光抢王自如的话("你不要打断我好吗").观点表达不出来. 二是老罗抓住了Zealer的弱点,一