[LeetCode] 1025. Divisor Game
Description
Alice and Bob take turns playing a game, with Alice starting first.
Initially, there is a number N on the chalkboard. On each player's turn, that player makes a move consisting of:
- Choosing any
xwith0 < x < NandN % x == 0. - Replacing the number
Non the chalkboard withN - x.
Also, if a player cannot make a move, they lose the game.
Return True if and only if Alice wins the game, assuming both players play optimally.
Example 1:
Input: 2
Output: true
Explanation: Alice chooses 1, and Bob has no more moves.
Example 2:
Input: 3
Output: false
Explanation: Alice chooses 1, Bob chooses 1, and Alice has no more moves.
Note:
1 <= N <= 1000
Analyse
黑板上有个整数N,每个人都作如下两个操作
- 选择一个整数
x,x满足0 < x < N和N % x == 0 - 将
N变成N - x
无法选择出满足条件的整数x时输
Alice先手
两个人作出的选择都是最优的
动态规划
-
定义dp[i] 为当
N为i,且轮到Alice选择时是否会胜利 -
找出递推关系
dp[i] = true ## 存在x,满足(dp[i - x] == false) && (N % x == 0) && (1 < x < N)
false ## 其他
给出初值
dp[0] = false
dp[1] = true
最终代码
bool divisorGame(int N) {
bool dp[N+1] = {false}; // 用false初始化为长度为N+1的dp数组
for (int i = 2; i <= N; i++) {
for (int x = 1; x < i; x++) {
if (i % x == 0) { // N % x == 0 ?
dp[i] = dp[i] || !dp[i-x]; // dp[i - x] == false ?
}
}
}
return dp[N];
}
找规律
对这道题来说,只有N一个输入,且N定义的是dp的长度,dp的值对于所有的N来说都是一样的,可以先手动算几个,这里计算N=6
| N | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| 结果 | x | √ | x | √ | x | √ |
N=2时,Alice选择x=1,胜
N=3时,Alice选择x=1,败
N=4时,Alice选择x=1,Bob面对N=3的情况,Alice胜,这里Alice如果选择2的话就输了(但题目说玩家做出的选择都是最优的)
N=5时,Alice选择x=1,Bob面对N=4的情况,Bob胜,Alice败
N=6时,Alice选择x=1,Bob面对N=5的情况,Bob败,Alice胜
看出规律,只要轮到Alice的时候N是偶数,Alice就赢定了
用位运算 (N & 1) == 0 来判断奇偶
bool divisorGame(int N) {
return (N & 1) == 0;
}
简单的证明
-
谁拿1谁就输
-
N为奇数时,Alice必输
奇数的因子也是奇的,无论Alice选什么,剩下的N-x为偶数,x < N,N-x至少为2,Bob再选1,N-x又变成了奇数,重复这个操作,最后Alice会拿到1 -
N为偶数时,Alice必胜
Alice每次选1,Bob就拿到了奇数,Alice胜

浙公网安备 33010602011771号