Leetcode 464. Can I Win 玩游戏 解题报告

本文介绍LeetCode上的464题——100游戏的一个变种。玩家轮流从1到maxChoosableInteger中选择数字,目标是使得累计和达到或超过desiredTotal。文章探讨了如何确保第一个玩家必胜的策略,通过DFS搜索配合状态缓存来解决此问题,但作者期待找到更优的数学解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 解体思想

题目前面是介绍了两个人玩100游戏。。后面出了个变种,我就不普及原始规则了,直接说新规则好了
两个人玩游戏,给了两个数maxChoosableInteger ,desiredTotal,从第一个人开始,可以从1到maxChoosableInteger 当中选一个数字(不能用用过的,第一个人第一轮可以随便选),加到当前的累计和当中(这个从0开始),若此时超过desiredTotal,那么第一个人赢,不然换第二个人,每个人开始前都不能选前面已经用过的数字,第二个人选一个数同样累加,若超过desiredTotal第二个人赢,不然交给第一个人,重复这个步骤

现在问说,有没有什么策略可以保证第一个一定赢?

我以为有什么数学方式,结果试了发现没有。。最后看了discuss还是只能dfs暴力解题,顺带加个map提速(因为可能会有重复状态)

代码基本就是照着discuss改的了,原来600ms ac的,现在127ms,不知道后面还能AC么

总觉得是不是有什么数学技巧?求指教

2 原题

In the "100 game," two players take turns adding, to a running total, any integer from 1..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 of 1..15 without replacement until they reach a total >= 100.
Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. 
You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. 
Example 
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.

3 AC解

public class Solution {
    public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
        if (desiredTotal<=0) return true;
        //如果1到最大能选的值所有和都不能满足目标值,那么肯定失败
        if (maxChoosableInteger*(maxChoosableInteger+1)/2<desiredTotal) return false;
        char state[] = new char[maxChoosableInteger];
        for(int i=0;i<maxChoosableInteger;i++) state[i] = '0';
        return dfs(desiredTotal, state, new HashMap<>());
    }
    private boolean dfs(int total, char[] state, HashMap<String, Boolean> hashMap) {
        String key= new String(state);
        if (hashMap.containsKey(key)) return hashMap.get(key);
        for (int i=0;i<state.length;i++) {
            if (state[i]=='0') {
                state[i]='1';
                if (total<=i+1 || !dfs(total-(i+1), state, hashMap)) {
                    hashMap.put(key, true);
                    state[i]='0';
                    return true;
                }
                state[i]='0';
            }
        }
        hashMap.put(key, false);
        return false;
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值