除数博弈
Divisor Game
解
方法一: 动态规划
在1到N的范围内,依据前面的推后面的。找出所有的解。
如果N存在约数,且下一个人不存在必胜策略,则当前人胜。
bool divisorGame(int N)
{
int dp[N + 1];
int i, j;
for (i = 0; i < N + 1; i++){
dp[i] = 0;
}
if (N <= 1){
return false;
}
dp[1] = 0;
dp[2] = 1;
for (i = 3; i < N + 1; i++){
for (j = 1; j < i / 2; j++){
if (i % j == 0 && dp[i - j] == 0){ //存在约数且下一轮没有必胜策略
dp[i] = 1;
break;
}
}
}
return dp[N] == 1;
}
结果
方法二:数学归纳
看到这道题的第一反应就是 “这就是道纯数学题。”
类似于找必胜策略,我们只需要找到一种胜利的方法就行。
- 如果N为奇数,那么它的所有因数全为奇数,开始时,Alice拿到奇数,
N-x
后得到的一定是偶数(即Bob拿到的是偶数),Bob只需要将这个数 -1,让Alice再拿到一个奇数,最后,Bob一定会得到范围内的最小偶数2
,Alice就输了,因此Bob有必胜策略。 - 如果N为偶数,Alice只需将其 -1,Bob就会拿到奇数,根据上面的分析,Alice有必胜策略。
综合上面的分析,只要N是偶数,Alice就可以胜。因此,代码就很简单了。
bool divisorGame(int N){
return N % 2 == 0;
}
结果