464. 我能赢吗

464. 我能赢吗

原题链接:

464. 我能赢吗

https://leetcode.cn/problems/can-i-win/description/

完成情况:

解题思路:

这段代码是一个用于解决一个游戏问题的Java类。该问题是"我能赢吗?",其中两个玩家轮流从1到maxChoosableInteger中选择数字,目标是达到或超过desiredTotal。代码中使用了深度优先搜索(DFS)算法来判断第一个玩家是否能赢得游戏。

  1. canIWin方法:首先检查如果所有可选数字的和都小于desiredTotal,则第一个玩家无法赢得游戏,直接返回false。否则,调用dfs方法开始搜索。

  2. dfs方法:这是深度优先搜索的核心方法。它接受四个参数:maxChoosableInteger(可选数字的最大值)、usedNumbers(已经选择的数字的状态)、desiredTotal(目标总和)、currentTotal(当前总和)。

在dfs方法中,首先检查是否已经计算过当前usedNumbers状态的结果,如果是,则直接返回结果。然后,遍历所有未选择的数字,尝试选择每个数字,更新状态并递归调用dfs方法。递归调用中,如果下一个玩家无法赢得游戏,则当前玩家可以赢得游戏,更新结果为true。

最后,将计算结果存储在memo中,以便在后续递归调用中可以直接获取结果。最终返回usedNumbers状态对应的结果。

这段代码利用了记忆化搜索技术,避免了重复计算,提高了效率。通过递归搜索所有可能的情况,判断第一个玩家是否可以在游戏中获胜。

参考代码:

_464我能赢吗_算法博弈论_dp

java 复制代码
package leetcode板块;

public class _464我能赢吗_算法博弈论_dp {
    int n,t;
    int [][] dp_canIWin = new int[1<<20][2];
    /**
     * 1 <= maxChoosableInteger <= 20
     * 0 <= desiredTotal <= 300
     * @param maxChoosableInteger   [1,该值]   取值范围
     * @param desiredTotal  目标累计和,大于等于均可
     * @return
     */
    public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
        /*
        在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和 达到或超过  100 的玩家,即为胜者。
        如果我们将游戏规则改为 "玩家 不能 重复使用整数" 呢?
        例如,两个玩家可以轮流从公共整数池中抽取从 1 到 15 的整数(不放回),直到累计整数和 >= 100。
        给定两个整数 maxChoosableInteger (整数池中可选择的最大数)和 desiredTotal(累计和),若先出手的玩家能稳赢则返回 true ,否则返回 false 。
         */
        //要一定获胜,那么就是必须,就盯着最大取值的跳一个数一直取
        n = maxChoosableInteger;
        t = desiredTotal;
        if (t<=maxChoosableInteger){
            return true;
        }
        return dfs_canIWin(0,0,0) == 1;
    }

    /**
     * 1 -> true   ||  -1 -> false
     * @param state  当前数的状态
     * @param curTotal  目前的累计和
     * @param kRound    第K轮
     * @return
     */
    private int dfs_canIWin(int state, int curTotal, int kRound) {
        if (state == ((1 << n) - 1) && curTotal < t)    return -1;
        if (dp_canIWin[state][kRound % 2] != 0)   return dp_canIWin[state][kRound % 2];
        int hope = kRound % 2 == 0 ? 1 : -1;
        for (int i = 0;i<n;++i){
            if (((state >> i) & 1) == 1)    continue;
            if (curTotal + i + 1 >= t)  return dp_canIWin[state][kRound % 2] = hope;
            if (dfs_canIWin(state | (1 << i),curTotal + i + 1,kRound+1) == hope)    return dp_canIWin[state][kRound % 2] = hope;
        }
        return dp_canIWin[state][kRound % 2] = -hope;
    }
}

_464我能赢吗_记忆化搜索_状态压缩

java 复制代码
package leetcode板块;

import java.util.HashMap;
import java.util.Map;

public class _464我能赢吗_记忆化搜索_状态压缩 {
    Map<Integer,Boolean> memoryMap = new HashMap<Integer, Boolean>();
    /**
     *
     * @param maxChoosableInteger
     * @param desiredTotal
     * @return
     */
    public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
        if ((1+maxChoosableInteger) * (maxChoosableInteger) / 2 < desiredTotal){
            return false;
        }
        return dfs_canIWin(maxChoosableInteger,0,desiredTotal,0);
    }

    /**
     *
     * @param maxChoosableInteger
     * @param usedNumbers
     * @param desiredTotal
     * @param curTotal
     * @return
     */
    private boolean dfs_canIWin(int maxChoosableInteger, int usedNumbers, int desiredTotal, int curTotal) {
        if (!memoryMap.containsKey(usedNumbers)){
            boolean result = false;
            for (int i = 0;i < maxChoosableInteger;i++){
                if (((usedNumbers >> i) & 1) == 0){
                    if (i + 1 + curTotal >= desiredTotal){
                        result = true;
                        break;
                    }
                    if (!dfs_canIWin(maxChoosableInteger,usedNumbers | (1 << i),desiredTotal,curTotal)){
                        result = true;
                        break;
                    }
                }
            }
            memoryMap.put(usedNumbers,result);
        }
        return memoryMap.get(usedNumbers);
    }
}
相关推荐
熬了夜的程序员1 天前
【LeetCode】83. 删除排序链表中的重复元素
算法·leetcode·链表
胖咕噜的稞达鸭1 天前
AVL树手撕,超详细图文详解
c语言·开发语言·数据结构·c++·算法·visual studio
张较瘦_1 天前
环境搭建 | [入门级]VSCode(Cursor|Trae|Qoder)搭建Java(Springboot3)企业开发环境全流程
java·ide·vscode
007php0071 天前
百度面试题解析:synchronized、volatile、JMM内存模型、JVM运行时区域及堆和方法区(三)
java·开发语言·jvm·缓存·面试·golang·php
YSRM1 天前
Leetcode+Java+图论II
java·leetcode·图论
十铭忘1 天前
基于SAM2的眼动数据跟踪2
java·服务器·前端
熊猫钓鱼>_>1 天前
Rust语言特性深度解析:所有权、生命周期与模式匹配之我见
算法·rust·软件开发·函数·模式匹配·异步编程·质量工具
okjohn1 天前
浅谈需求分析与管理
java·架构·系统架构·软件工程·产品经理·需求分析·规格说明书
芒果量化1 天前
Optuna - 自动调参利器&python实例
开发语言·python·算法·机器学习
麦麦大数据1 天前
D025 摩托车推荐价格预测可视化系统|推荐算法|机器学习|预测算法|用户画像与数据分析
mysql·算法·机器学习·django·vue·推荐算法·价格预测