我能赢吗

2021-03-30  本文已影响0人  小幸运Q

image.png

特例一:如果最大能选择的数字maxChoosableInteger比期望的总数desiredTotal要大,先手稳赢,返回True

特例二:如果能选择的所有数字总和比期望的总数desiredTotal要小,一定到达不了desiredTotal,先手稳输,返回False

if(maxChoosableInteger>desiredTotal){
  return True
}
if((1+maxChoosableInteger)*maxChoosableInteger/2 < desiredTotal){
  return False
}

用二进制位来标记某个数是否已被选择,比如01表示1已被选择,10表示2已被选择,11表示1和2都被选择,100表示3被选择,以此类推,1 << (n - 1)1<<(n−1) 表示n已被选择

情况1我抽牌:只要我出某一张牌,对方遍历了所有方法helper(statenow|choosedpoint,value,desired)都是输那我就赢了。
情况2对手抽牌:不论对方抽哪张牌都是死。

class Solution:
    # return 0 我稳输 1 我稳赢
    def helper(self,dp,state,value,maxChoosableInteger,desiredTotal,terms):
        if(dp[state]!=10):
            return dp[state]
        if terms%2==1:
            # 我执手,对手有一种情况全输即可,helper有一个返回1我就能赢
            res=0
            for i in range(0,maxChoosableInteger):
                if res==1:
                    break
                if state&(1<<i)==0:
                    if(value+i+1>=desiredTotal):
                        # now
                        res=1
                        break
                    else:
                        res|=self.helper(dp,state+(1<<i),value+i+1,maxChoosableInteger,desiredTotal,terms+1)
            if(res==1):
                dp[state]=1
                return 1
            else:
                dp[state]=0
                return 0
        else:
            # 对手执手,我helper得全赢helper全返回1我才能赢
            res=1
            for i in range(0,maxChoosableInteger):
                if res==0:
                    break
                if state&(1<<i)==0:
                    if(value+i+1>=desiredTotal):
                        res=0
                        break
                    else:
                        res&=self.helper(dp,state+(1<<i),value+i+1,maxChoosableInteger,desiredTotal,terms+1)
            if(res==1):
                dp[state]=1
                return 1
            else:
                dp[state]=0
                return 0

    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
        # 特殊情况两种
        if desiredTotal<=maxChoosableInteger:
            return True
        if((1+maxChoosableInteger)*maxChoosableInteger/2 < desiredTotal):
            return False
        dp=[10 for i in range(1<<maxChoosableInteger)]
        return self.helper(dp,0,0,maxChoosableInteger,desiredTotal,1)==1
上一篇下一篇

猜你喜欢

热点阅读