leetcode-dp-博弈问题-除数博弈


package dp.divisorGame;

/**
 * 1025. 除数博弈
 * 爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
 * 

* 最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作: *

* 选出任一 x,满足 0 < x < N 且 N % x == 0 。 * 用 N - x 替换黑板上的数字 N 。 * 如果玩家无法执行这些操作,就会输掉游戏。 *

* 只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 False。假设两个玩家都以最佳状态参与游戏。 *

*

*

* 示例 1: *

* 输入:2 * 输出:true * 解释:爱丽丝选择 1,鲍勃无法进行操作。 * 示例 2: *

* 输入:3 * 输出:false * 解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。 *

*

* 提示: *

* 1 <= N <= 1000 * 通过次数78,570提交次数110,824 */ public class divisorGame { /** * N = 1时,很明显Alice无法写任何数,失败; * N = 2时,Alice只能写1,于是根据上面的结论,Bob无法写任何数,失败,Alice获胜; * N = 3时,3的唯一小于它的约数为1,Alice只能写2,于是根据上面的结论,Alice失败; * N = 4时,Alice可以写3,于是Bob失败,她获胜; * 总而言之,当N为奇数时,Alice失败,而当N为偶数时,Alice获胜。 *

* 递推公式 i%j==0 && !dp[i-j] * 解释 i代表从i到N,j代表从1到N-1,如果存在合适的除数,就判断N-i的那个位置后手人的状态。 * * @param n * @return */ public static boolean divisorGame(int n) { if (n == 1) { return false; } boolean[] dp = new boolean[n + 1]; dp[1] = false; for (int i = 2; i <= n; i++) { for (int j = 1; j < i; j++) { if (i % j == 0 && !dp[i - j]) { dp[i] = true; } } } return dp[n]; } public static void main(String[] args) { System.out.println(divisorGame(3)); } }

相关