题目:
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 n 。在每个玩家的回合,玩家需要执行以下操作:
- 选出任一
x,满足0 < x < n且n % x == 0。 - 用
n - x替换黑板上的数字n。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 true 。假设两个玩家都以最佳状态参与游戏。
算法:
方法一:动态规划
n = 1, x取值范围(0,1),没有满足条件的x,我方先手必败。
n = 2, x=(0,2),我方先手只能取x = 1, n = n - x = 1,对方进入第一种情况,对方必败,我方先手必胜。
n = 3, x=(0,3),
1)我方先手取x = 1,对方进入n = 2情况,如上讨论,对方必胜。
2)我方先手不能取x = 2,
综上,此时我方先手必败。
.......
根据这个关系,构造转移状态,n=i时,只要能让对方进入dp[n-i]=false,说明我方存在必胜选择。
func divisorGame(n int) bool {
// dp表示n取值(0,n)过程中,是否存在必胜法则
dp := make([]bool, n + 2)
dp[1] = false
dp[2] = true
for i := 3; i <= n; i ++ {
for x := 1; x < i; x ++ {
// 可以让对面必败,则dp[i]可以必胜
if i % x == 0 && !dp[i - x] {
dp[i] = true
break
}
}
}
return dp[n]
}