题目:除数博弈
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
选出任一 x,满足 0 < x < N 且 N % x == 0 。
用 N - x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。
示例
示例 1:
输入:2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。
示例 2:
输入:3
输出:false
解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。
提示:
- 1 <= N <= 1000
使用JavaScript语言
/**
* @param {number} N
* @return {boolean}
*/
var divisorGame = function(N) {
var dp = [];
dp[1] = false; //N==1时必输
dp[2] = true; //N==2时必胜
for(var i = 3; i <= N;i++){
dp[i] = false;
for(var j = 1;j < i;j++){
if((dp[i-j]==false)&&(i%j == 0)){ //若j是i的余数且dp[i-j]为假(0)的话,则代表当前为真(1)
dp[i] = true;
break; //只要出现一次就可以
}
}
}
// console.log(dp[N])
return dp[N]
};
分析
归纳法:
- 最终结果应该是占到 2 的赢,占到 1 的输;
- 若当前为奇数,奇数的约数只能是奇数或者 1,因此下一个一定是偶数;
- 若当前为偶数, 偶数的约数可以是奇数可以是偶数也可以是 1,因此直接减 1,则下一个是奇数;
- 因此,奇则输,偶则赢。
动态规划:
- 将所有的小于等于 N 的解都找出来,基于前面的,递推后面的。
- 状态转移: 如果 i 的约数里面有存在为 False 的(即输掉的情况),则当前 i 应为 True;如果没有,则为 False。
- n=3之后,先走的如果想赢(爱丽丝如果想赢),就需要找到小于n的数k,能使得在符合条件(n%k==0)的基础上还能让n-k(下一局的n)是先走输。(即n-k的最优解是输,即下一局的人再怎么聪明也是输。)
- 即在内层循环中如果找到一个数使得if((dp[i-j]==false)&&(i%j==0)),那么该数是先走赢,一层循环走下来找不到这么一个数的话,那么该数是先走输。故只要找到一个符合条件就可以直接跳出循环了。
题目链接
leetcode-cn.com/problems/di…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!