我能赢吗

在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和达到 100 的玩家,即为胜者。

如果我们将游戏规则改为 "玩家不能重复使用整数" 呢?

例如,两个玩家可以轮流从公共整数池中抽取从 1 到 15 的整数(不放回),直到累计整数和 >= 100。

给定一个整数 maxChoosableInteger (整数池中可选择的最大数)和另一个整数 desiredTotal(累计和),判断先出手的玩家是否能稳赢(假设两位玩家游戏时都表现最佳)?

你可以假设 maxChoosableInteger 不会大于 20, desiredTotal 不会大于 300。

示例:

输入:

maxChoosableInteger = 10

desiredTotal = 11

输出:

false

解释:

无论第一个玩家选择哪个整数,他都会失败。

第一个玩家可以选择从 1 到 10 的整数。

如果第一个玩家选择 1,那么第二个玩家只能选择从 2 到 10 的整数。

第二个玩家可以通过选择整数 10(那么累积和为 11 >= desiredTotal),从而取得胜利.

同样地,第一个玩家选择任意其他整数,第二个玩家都会赢。

DFS + memorizatoin

通过state保存状态,即当前选了哪些数

需要注意maxChoosableInteger不会大于20,我们完全可以通过一个32位的整数来表示状态

例如选择了1和2,那么状态为01 | 10 = 11 = 3(选择的数为1左移位数-1)

 class Solution {
public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
if(desiredTotal <= maxChoosableInteger)
return true;
//Note: n should be <= 32 as int is 32-bit in Java; else it will 1 << 33+ equals 0.
int n = maxChoosableInteger;
int sum = n * (n + 1) / 2;
if(sum < desiredTotal)
return false;
Boolean[] dp = new Boolean[1 << n];
return canIWin(0, n, desiredTotal, dp);
} private boolean canIWin(int state, int n, int remain, Boolean[] dp) {
if (remain <= 0) {
//dp[state] = false;
// Base case:
return false;
}
if (dp[state] == null) {
dp[state] = false;
int mask = 1;
//Key Point: take from the tail
for(int i = 1; i <= n; i++){
int future = state | mask;
//the other can win
if (future != state && !canIWin(future, n, remain - i, dp)) {
//update current status = true
dp[state] = true;
break;
}
mask <<= 1;
}
}
return dp[state];
}
}


Leetcode 464.我能赢吗的更多相关文章

  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. LeetCode 464. Can I Win

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

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

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

  5. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  6. C#LeetCode刷题-动态规划

    动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串   22.4% 中等 10 正则表达式匹配   18.8% 困难 32 最长有效括号   23.3% 困难 44 通配符匹配   17.7% ...

  7. LeetCode刷题总结-动态规划篇

    本文总结LeetCode上有动态规划的算法题,推荐刷题总数为54道.具体考点分析如下图: 1.中心扩展法 题号:132. 分割回文串 II,难度困难 2.背包问题 题号:140. 单词拆分 II,难度 ...

  8. leetcode动态规划题目总结

    Hello everyone, I am a Chinese noob programmer. I have practiced questions on leetcode.com for 2 yea ...

  9. C#LeetCode刷题-极小化极大

    极小化极大篇 # 题名 刷题 通过率 难度 375 猜数字大小 II   23.4% 中等 464 我能赢吗   25.5% 中等 486 预测赢家   40.4% 中等 843 猜猜这个单词   2 ...

随机推荐

  1. 用jQuery实现jsonp跨域

    跨域的安全限制都是指浏览器端来说的.服务器端是不存在跨域安全限制的,所以通过本机服务器端通过类似httpclient方式完成“跨域访问”的工作,然后在浏览器端用AJAX获取本机服务器端“跨域访问”对应 ...

  2. dedecms会员中心编辑器无法上传图片

    文件:include\dialog\config.php 找到这行代码: $cuserLogin = new userLogin(); 把上面代码下面的这些注释掉: if($cuserLogin-&g ...

  3. FAST FW150R软件版本升级解决一些网页无法加载问题

    家里用的移动宽带,通过无线路由器无线上网.上taobao.天猫都很快,但是一上京东.苏宁易购界面加载很慢,界面无法显示,怀疑是无线路由问题,然后直接通过网线相连接,发现问题消失,决定对无线路由软件版本 ...

  4. 从零开始的Lua宅[1]:编译Lua解释器

    Lua是一门神奇的脚本语言,游戏宅必备,懒人必备.Lua差多不是学起来用起来最简单的语言了,以至于简单到自身就是文档,自身就是配置文件.但是Lua的运行效率却是众多脚本中非常高的,据说仅次于V8爹下的 ...

  5. 转载 - 浅析我曾遇到的几个便宜VPS服务器

    本文来自:http://www.jianshu.com/p/7d8cfa87fa32 有些时候可能并不是我们工作和业务的需要,但是网上就是这么的邪门,如果看到便宜的衣服不去购买深怕自己吃亏.所以每年的 ...

  6. LibreOJ #514. 「LibreOJ β Round #2」模拟只会猜题意

    内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 给定一个长度为 nnn 的序列 AAA . 定义 f(l,r)=∑i=lrAif(l,r ...

  7. python爬虫之路——Python的re模块及其方法

    介绍常用的三种方法:search(),sub(),findall() search():匹配并提取第一个符合规律的内容,然后返回一个正则表达式的对象 #提取字符串中的第一个数字 import re a ...

  8. python_105_类的特殊成员方法

    aa.py class C(): def __init__(self): self.name='QiZhiguang' 类的特殊成员方法: # 1. __doc__ 表示类的描述信息 class Do ...

  9. 理解AttributeUsage类

    类定义: // 摘要: // 指定另一特性类的用法. 此类不能被继承. [Serializable] [AttributeUsage(AttributeTargets.Class, Inherited ...

  10. iOS 设置随意屏幕旋转

    方法一,通过控制器继承或分类实现: 在UITabBarController 的子类或分类中实现 - (BOOL)shouldAutorotate { return [self.selectedView ...