1025.除数博弈

124 阅读1分钟

题目:
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。

最初,黑板上有一个数字 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]
}