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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/can-i-win
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

带储存的dfs算法,用一个map<Integer, Boolean>放置当前如果到达了某个状态,即已经被选了某些数字的场景,这个状态能不能赢。Integer用位来表示,哪些被选中了的,如integer为5,那它的二进制表示是101,那就表示了,当第1个与第3个数字(即1和3)被选中后的这个状态,是不是就赢了。

class Solution {
    public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
        if (maxChoosableInteger >= desiredTotal)
            return true;
        if (maxChoosableInteger * (maxChoosableInteger + 1) / 2 < desiredTotal)
            return false;
        // 用dp来放置某个状态的结果。
        // key是integer,表示的是当前某个状态,
        // 如integer为5,那它的二进制表示是101,那就表示了,当第1个与第3个数字(即1和3)被选中后的这个状态,是不是就赢了。
        Map <Integer, Boolean> dp = new HashMap<>();
        return canWin(desiredTotal, maxChoosableInteger, dp, 0);
    }

    private boolean canWin(int desiredTotal, int maxChoosableInteger, Map<Integer, Boolean> dp, int state) {
        if (dp.containsKey(state)) {
            return dp.get(state);
        }
        for (int i = 1; i <= maxChoosableInteger; i++) {
            // 把当前要数字对应的位,与当前状态进行与操作,如果结果是0,说明没有被用过,如果结果是1,说明被用到过了。
            boolean unVisited = (( 1 << i ) & state) == 0;
            if (unVisited) {
                // 如果选择了i,已经满足了要求,那么当到达这个状态时,做选择的人能赢
                // 如果不能满足要求,那么就看desiredTotal - i如果不能满足,那么desiredTotal肯定满足,因为i还没有被选嘛。
                if (desiredTotal <= i || !canWin(desiredTotal - i, maxChoosableInteger, dp, (( 1 << i ) | state)) ) {
                    dp.put(state, true);
                    return true;
                }
            }
        }
        dp.put(state, false);
        return false;
    }
}

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值