题目
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 n 。在每个玩家的回合,玩家需要执行以下操作:
选出任一 x,满足 0 < x < n 且 n % x == 0 。
用 n - x 替换黑板上的数字 n 。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 true 。假设两个玩家都以最佳状态参与游戏。
示例
示例1
输入:n = 2
输出:true
解释:爱丽丝选择 1 ,鲍勃无法进行操作。
示例2
输入:n = 3
输出:false
解释:爱丽丝选择 1 ,鲍勃也选择 1 ,然后爱丽丝无法进行操作。
解法一、数学推导
首先,可以推出,游戏的结束条件时n= 2
因为当一个人拿到2 时,那么他只能选择x= 1 ,然后n= 1 ,对方就输了,所以拿到n= 2 的一方一定会赢
爱丽丝拿到的数字有两种情况,奇数和偶数
且奇数的约数只能是奇数,而偶数的约数可以是奇数也可以是偶数
1 、当爱丽丝拿到偶数时,如果她选择1 为约数,那么留给对手的永远时奇数,对手只能选择另外一个奇数作为约数,
又奇数- 奇数= 偶数,所有留给爱丽丝的永远是偶数,即n= 2 时,一定在爱丽丝手上,所有爱丽丝肯定赢
2 、当爱丽丝拿到奇数,约数一定是奇数,那么留给对方的就是偶数,由1 可知,对手肯定赢
因此,当爱丽丝拿到偶数时必胜,当爱丽丝拿到奇数时必败
代码
class Solution {
public boolean divisorGame ( int n) {
return n % 2 == 0 ;
}
}
有些同学可能会质疑,爱丽丝如果没有那么聪明,当拿到偶数时,也留给对方一个偶数不就输了
但是题目有一句话:假设两个玩家都以最佳状态参与游戏。
所以双方都会执行最优解
解法二、动态规划
动态规划的思想比较简单,记录(1 ,n)上所有的结果,当计算n- x时,直接查找dp表
又因为时交替的进行,因此n[ i] = ! n[ i- x]
class Solution {
public boolean divisorGame ( int n) {
boolean [ ] dp = new boolean [ n + 2 ] ;
dp[ 1 ] = false ;
dp[ 2 ] = true ;
for ( int i = 3 ; i < dp. length; i++ )
{
for ( int j = 1 ; j < i; j++ )
{
if ( ( i % j == 0 ) && dp[ i - j ] != true )
{
dp[ i] = true ;
break ;
}
}
}
return dp[ n] ;
}
}
大家如果有好的想法可以在评论区一起讨论