原题链接
- 这道题我看到leetcode上有个巧妙解法,利用N的奇偶性就可以判断先手的输赢;
1. 最终结果应该是谁先占到 2 谁就赢;
2. 若当前为奇数,奇数的约数只能是奇数或者 1,因此下一个一定是偶数;
3. 若当前为偶数,偶数的约数可以是奇数可以是偶数也可以是 1,所以为保证胜利,因此直接减 1,则下一个是奇数;
4. 因此,奇则输,偶则赢。直接:
代码如下:
class Solution {
public boolean divisorGame(int N) {
return N % 2 == 0;
}
}
- 但是看到这道题目属于动态规划,那么就该朝着动态规划的思路去做,但是我觉得这道题虽然是简单题,但是有点绕。
1. 定义状态,用dp[i]来表示玩家的输赢,因为是自底向上,所以只要保证爱丽丝在dp[N]的时候是true就可以了;
2. 寻找状态转移方程,我们试想,首先需要满足的是找到一个x使得(i%x==0),然后在这个基础上,只要保证让下一个
dp[i-x]==false,即让下一个先走的为输。
class Solution {
public boolean divisorGame(int N) {
boolean[] dp = new boolean[1001];
dp[1] = false;
dp[2] = true;
for(int i=3;i<=N;i++){
dp[i] = false;
for(int j=1;j<i;j++){
if(dp[i-j] == false && (i%j == 0)){
dp[i] = true;
break;
}
}
}
return dp[N];
}
}