状态压缩-bitmask

文章讨论了一个两人游戏,玩家轮流从1到最大整数中选择一个数,目标是使得累加和首先达到或超过特定总和。当玩家不能重复选择数字时,判断先手玩家是否能通过最优策略获胜。给定最大可选整数和目标总和,代码实现了一个深度优先搜索的解决方案来确定先手是否必胜。
摘要由CSDN通过智能技术生成

[464]Can I Win

# In the "100 game" two players take turns adding, to a running total, any 
# integer from 1 to 10. The player who first causes the running total to reach or 
# exceed 100 wins. 
# 
#  What if we change the game so that players cannot re-use integers? 
# 
#  For example, two players might take turns drawing from a common pool of 
# numbers from 1 to 15 without replacement until they reach a total >= 100. 
# 
#  Given two integers maxChoosableInteger and desiredTotal, return true if the 
# first player to move can force a win, otherwise, return false. Assume both 
# players play optimally. 
# 
#  
#  Example 1: 
# 
#  
# Input: maxChoosableInteger = 10, desiredTotal = 11
# Output: false
# Explanation:
# No matter which integer the first player choose, the first player will lose.
# The first player can choose an integer from 1 up to 10.
# If the first player choose 1, the second player can only choose integers from 
# 2 up to 10.
# The second player will win by choosing 10 and get a total = 11, which is >= 
# desiredTotal.
# Same with other integers chosen by the first player, the second player will 
# always win.
#  
# 
#  Example 2: 
# 
#  
# Input: maxChoosableInteger = 10, desiredTotal = 0
# Output: true
#  
# 
#  Example 3: 
# 
#  
# Input: maxChoosableInteger = 10, desiredTotal = 1
# Output: true
#  
# 
#  
#  Constraints: 
# 
#  
#  1 <= maxChoosableInteger <= 20 
#  0 <= desiredTotal <= 300 
#  


# leetcode submit region begin(Prohibit modification and deletion)
class Solution:

    def __init__(self):
        self.mem = {}

    def dfs(self, mci, dt, state, sum_):
    	# 这个是必须的,不然后手self.dfs(mci, dt, state | 1 << i - 1, sum_ + i)返回False, 导致先手的结果为True
        if mci * (mci + 1) / 2 < dt:
            self.mem[state] = False
            return False
        if state in self.mem:
            return self.mem[state]
        # 注意range的起始和结束的区间
        for i in range(1, mci + 1):
        	# 状态从0号bit为开始, 所以为i-1
            if 1 << i - 1 & state:
                continue
            #先手的求和大于i或者后手的结果为False
            if sum_ + i >= dt or not self.dfs(mci, dt, state | 1 << i - 1, sum_ + i):
                self.mem[state] = True
                return True
        self.mem[state] = False
        return False

    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
        self.dfs(maxChoosableInteger, desiredTotal, 0, 0)
        return self.mem[0]


# leetcode submit region end(Prohibit modification and deletion)


if __name__ == '__main__':
    so = Solution()
    maxChoosableInteger = 5
    desiredTotal = 50
    res = so.canIWin(maxChoosableInteger, desiredTotal)
    print(res)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值