Leetcode 464.我能赢吗
我能赢吗
在 "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.我能赢吗的更多相关文章
- 状态压缩 - LeetCode #464 Can I Win
动态规划是一种top-down求解模式,关键在于分解和求解子问题,然后根据子问题的解不断向上递推,得出最终解 因此dp涉及到保存每个计算过的子问题的解,这样当遇到同样的子问题时就不用继续向下求解而直接 ...
- [LeetCode] 464. Can I Win 我能赢吗
In the "100 game," two players take turns adding, to a running total, any integer from 1.. ...
- LeetCode 464. Can I Win
In the "100 game," two players take turns adding, to a running total, any integer from 1.. ...
- [leetcode] 464. Can I Win (Medium)
原题链接 两个人依次从1~maxNum中选取数字(不可重复选取同一个),累和.当一方选取数字累和后结果大于等于给定的目标数字,则此人胜利. 题目给一个maxNum和targetNum,要求判断先手能否 ...
- Swift LeetCode 目录 | Catalog
请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift 说明:题目中含有$符号则为付费题目. 如 ...
- C#LeetCode刷题-动态规划
动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串 22.4% 中等 10 正则表达式匹配 18.8% 困难 32 最长有效括号 23.3% 困难 44 通配符匹配 17.7% ...
- LeetCode刷题总结-动态规划篇
本文总结LeetCode上有动态规划的算法题,推荐刷题总数为54道.具体考点分析如下图: 1.中心扩展法 题号:132. 分割回文串 II,难度困难 2.背包问题 题号:140. 单词拆分 II,难度 ...
- leetcode动态规划题目总结
Hello everyone, I am a Chinese noob programmer. I have practiced questions on leetcode.com for 2 yea ...
- C#LeetCode刷题-极小化极大
极小化极大篇 # 题名 刷题 通过率 难度 375 猜数字大小 II 23.4% 中等 464 我能赢吗 25.5% 中等 486 预测赢家 40.4% 中等 843 猜猜这个单词 2 ...
随机推荐
- 判断浏览器是pc端还是移动端
var browser = { versions: function() { var u = navigator.userAgent, app = navigator.appVersion; retu ...
- postgres创建库时指定编码格式
postgres新建数据库时如果没有指定编码格式,会用默认的编码格式: 对于已经存在的数据库,虽然可以用:set client_encoding to 'UTF8'; set server_encod ...
- python 之format字符串格式化
print函数之format字符串格式化方法的使用与学习笔记. 一.映射关系 (1)“映射”示例,以下通过位置举例说明: [+]Example_1: >>> print(" ...
- UVALive 5031 Graph and Queries (Treap)
删除边的操作不容易实现,那么就先离线然后逆序来做. 逆序就变成了合并,用并存集判断连通,用Treap树来维护一个连通分量里的名次. Treap = Tree + Heap.用一个随机的优先级来平衡搜索 ...
- UVA 11468 Substring (AC自动机)
用把失配边也加到正常边以后AC自动机,状态是长度递减的DAG,每次选一个不会匹配字符的转移. dp[u][L]表示当前在tire树上u结点长度还剩L时候不匹配的概率,根据全概率公式跑记忆化搜索. #i ...
- ECshop安装提示cls_image::gd_version() 和不支持JPEG
ecshop版本:ECShop_V2.7.3_UTF8_release1106php 版本 5.5--------------------------------------------------- ...
- Oracle SQL语句性能优化方法大全
Oracle SQL语句性能优化方法大全 下面列举一些工作中常常会碰到的Oracle的SQL语句优化方法: 1.SQL语句尽量用大写的: 因为oracle总是先解析SQL语句,把小写的字母转换成大写的 ...
- 【转】pDc->SelectObject(pOldBrush)恢复画刷
请看下面的代码: CDC *pDc=new CClientDC(this); CBrush brush; brush.CreateSolidBrush(RGB(0,255,0)); CBrush * ...
- SAP HANA
DROP PROCEDURE ""."ZCONCAT_EKKO_EBN"; CREATE PROCEDURE ""."ZCONCA ...
- MySql常用数据操作
1.数据库操作: MySQL服务管理命令: 1.启动服务:sudo service mysql start 2.停止服务:sudo service mysql stop 3.重新启动服务:sudo s ...