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.

这道题给了我们一堆数字,然后两个人,每人每次选一个数字,看数字总数谁先到给定值,有点像之前那道 Nim Game,但是比那题难度大。我刚开始想肯定说用递归啊,结果写完发现 TLE 了,后来发现我们必须要优化效率,使用 HashMap 来记录已经计算过的结果。我们首先来看如果给定的数字范围大于等于目标值的话,直接返回 true。如果给定的数字总和小于目标值的话,说明谁也没法赢,返回 false。然后我们进入递归函数,首先我们查找当前情况是否在 HashMap 中存在,有的话直接返回即可。我们使用一个整型数按位来记录数组中的某个数字是否使用过,我们遍历所有数字,将该数字对应的 mask 算出来,如果其和 used 相与为0的话,说明该数字没有使用过,我们看如果此时的目标值小于等于当前数字,说明已经赢了,或者调用递归函数,如果返回 false,说明也是第一个人赢了。为啥呢,因为当前已经选过数字了,此时就该对第二个人调用递归函数,只有返回的结果是 false,我们才能赢,所以此时我们 true,并返回 true。如果遍历完所有数字,标记 false,并返回 false,参见代码如下:

class Solution {
public:
bool canIWin(int maxChoosableInteger, int desiredTotal) {
if (maxChoosableInteger >= desiredTotal) return true;
if (maxChoosableInteger * (maxChoosableInteger + ) / < desiredTotal) return false;
unordered_map<int, bool> m;
return canWin(maxChoosableInteger, desiredTotal, , m);
}
bool canWin(int length, int total, int used, unordered_map<int, bool>& m) {
if (m.count(used)) return m[used];
for (int i = ; i < length; ++i) {
int cur = ( << i);
if ((cur & used) == ) {
if (total <= i + || !canWin(length, total - (i + ), cur | used, m)) {
m[used] = true;
return true;
}
}
}
m[used] = false;
return false;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/464

类似题目:

Nim Game

Flip Game II

Guess Number Higher or Lower II

Predict the Winner

参考资料:

https://leetcode.com/problems/can-i-win/

https://leetcode.com/problems/can-i-win/discuss/95283/brute-force-and-memoization

https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 464. Can I Win 我能赢吗的更多相关文章

  1. 状态压缩 - LeetCode #464 Can I Win

    动态规划是一种top-down求解模式,关键在于分解和求解子问题,然后根据子问题的解不断向上递推,得出最终解 因此dp涉及到保存每个计算过的子问题的解,这样当遇到同样的子问题时就不用继续向下求解而直接 ...

  2. LeetCode 464. Can I Win

    In the "100 game," two players take turns adding, to a running total, any integer from 1.. ...

  3. 464 Can I Win 我能赢吗

    详见:https://leetcode.com/problems/can-i-win/description/ C++: class Solution { public: bool canIWin(i ...

  4. [leetcode] 464. Can I Win (Medium)

    原题链接 两个人依次从1~maxNum中选取数字(不可重复选取同一个),累和.当一方选取数字累和后结果大于等于给定的目标数字,则此人胜利. 题目给一个maxNum和targetNum,要求判断先手能否 ...

  5. [LeetCode] Can I Win 我能赢吗

    In the "100 game," two players take turns adding, to a running total, any integer from 1.. ...

  6. Leetcode 464.我能赢吗

    我能赢吗 在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和达到 100 的玩家,即为胜者. 如果我们将游戏规则改为 ...

  7. 464. Can I Win

    https://leetcode.com/problems/can-i-win/description/ In the "100 game," two players take t ...

  8. leetcode 学习心得 (2) (301~516)

    源代码地址:https://github.com/hopebo/hopelee 语言:C++ 301. Remove Invalid Parentheses Remove the minimum nu ...

  9. 【Leetcode周赛】从contest-91开始。(一般是10个contest写一篇文章)

    Contest 91 (2018年10月24日,周三) 链接:https://leetcode.com/contest/weekly-contest-91/ 模拟比赛情况记录:第一题柠檬摊的那题6分钟 ...

随机推荐

  1. MySQL优化常见Extra分析——慢查询优化

    数据准备: create table user ( id int primary key, name ), sex ), index(name) )engine=innodb; 数据说明:用户表:id ...

  2. SpringBoot2.x|Thymeleaf页面不能正常载入css、js文件

    1.实现实现WebMvcConfig配置类可以解决页面不能加载css,js的问题: 扩展SpringMvc,编写一个配置类(@Configuration),是WebMvcConfigurationAd ...

  3. Maven环境搭配及继承

    1. Maven简单介绍 Apache Maven是个项目管理和自动构建工具,基于项目对象模型(POM)的概念. 作用:完成项目的相关操作,如:编译,构建,单元测试,安装,网站生成和基于Maven部署 ...

  4. Python脚本1

    [轮子]P123. 求最大约数,并鉴别是否为素数

  5. 前端开发JS——数组

    25.数组 1)声明数组: ①构造函数创建数组 var arr = new Array(); console.log(arr):        //[]   var arr = new Array(2 ...

  6. 【原创】CentOS 7 安装airflow

    该文是基于python虚拟化环境来安装,非虚拟化也是一样,虚拟化我只是不想破环系统环境. 安装python虚拟环境 pip install virtualenv 设置环境变量 sudo vi /etc ...

  7. Linux创建高级用户并删除

    Linux创建高级用户并删除 常见window系统可以创建许多用户,但是linux也可以创建许多用户. 方法比window方便简单. (1)添加一个普通用户 :nangong(名字自己取) usera ...

  8. Confluence 6.9.0 安装

    平台环境:centos 7.6 数据库版本:mysql-5.7.26,提前安装好,安装步骤略. 软件版本:Confluence6.9.0 所需软件:提前下载到本地电脑 atlassian-conflu ...

  9. 使用spring aop 记录接口日志

    spring配置文件中增加启用aop的配置 <!-- 增加aop 自动代理配置 --> <aop:aspectj-autoproxy /> 切面类配置 package com. ...

  10. 201871010121-王方《面向对象程序设计JAVA》第十五周实验总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...