/**
* 1025. 除数博弈
* @author wsq
* @date 2020/10/15
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
选出任一 x,满足 0 < x < N 且 N % x == 0 。
用 N - x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 False。假设两个玩家都以最佳状态参与游戏。
示例 1:
输入:2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。
链接:https://leetcode-cn.com/problems/divisor-game
*/
package com.wsq.dp;
public class DivisorGame {
/**
* 给定数字N,判断先手 必胜 或 必败
* 1. 确定状态
* 最后一步:存在0<x<N, N-x时先手必败,对应下一步f[N]必胜
* 子问题:计算f[N-x]的状态
* 2.确定转移方程
* N % j == 0
* f[N] = !f[N-j]
* 3.初始条件与边界问题
* f[1] = false;
* f[0] = false;
* 4.计算顺序
* @param N
* @return
*/
public boolean divisorGame(int N) {
if(N < 2){
return false;
}
// 开数组
// f[N] 表示爱丽丝的获胜情况
// f[N] = !f[N-x]
boolean[] f = new boolean[N + 1];
for(int i = 2; i <= N; i++){
for(int j = 1; j < i; j++){
if(i % j == 0 && !f[i - j]){
f[i] = true;
break;
}
}
}
return f[N];
}
}