[dp]leetcode 1025. Divisor Game

输入:一个正整数N
输出:Alice赢,返回true,否则false
规则:黑板上给出一个数字N,ALice先选择。Bob后选择。他们可以选择一个数字 X,0<X<N并且N%X=0。一个人选择X以后,黑板上的数字变为N-X。
当一个人没有可以选择的数字的 时候,就输了。假设Alice和 Bob水平相同,状态相同。
分析:假设N=5。
Alice选择1,黑板数字 变为4。
Bob选择2或者1.
 Bob选择2,黑板 数字变为2。
  Alice选择1,黑板数字变为1。
  Bob没有可以选的,Alice赢。
 Bob选择1,黑板数字变为3
  Alice选择1,黑板数字变为2。
  Bob选择1,黑板数字变为1。
  Alice没有可以选的,Alice输。

Bob有两种选择,会导致Alice可能赢,也可能输。那结果应该是什么呢?题目中有一个条件是:Alice和 Bob水平相同,状态相同。他们应该会分析怎么选择才能让自己赢。我觉得这可能是题目的难点。我们使用归纳法总结一下。
从上面的分析看到,谁遇到数字1,谁会输。谁遇到数字2,谁就会赢。谁遇到数字3,谁会输。
那遇到数字4,只要让对方遇到数字3,自己就赢了。
那遇到遇到数字5呢?要让对方遇到数字3或者1,自己能赢,但是5%2不等于0,5%4不等于0,所以只能选择1,对方遇到数字4,对方赢。
我们需要一个dp,dp[i]=true表示Alice遇到数字i会赢,dp[i]=false表示Alice遇到数字i会输。

	public boolean divisorGame(int N) {
        boolean[] target = new boolean[N+1];
        target[1] = false;        
        if(N<=1) return false;
        target[2] = true;
        for(int x = 3;x<=N;x++){
            for(int y=1;y<=x/2;y++){
                if(x%y==0 && target[x-y]==false){
                    target[x]=true;
                    break;
                }
            }
        }
        return target[N];
    }

分析2:使用数学归纳法。
N=1,输
N=2,赢
N=3,输
N=4,赢
假设 N=奇数,输,N=偶数,赢。
那么当N=n+1时,如果n是偶数,N一定是奇数。如果想要赢,我们一定要选一个偶数,留给对方一个奇数。但是N是奇数,N的约数只有1,我们只能选择1,剩下一个偶数给对方。所以我们一定会输。
如果n是奇数,N一定是偶数。如果想要赢,我们一定要留给对方一个奇数,那我们可以选择一个奇数,可以直接选择1,留一个奇数给对方。我们一定会赢。
假设成立。

	public boolean divisorGame(int N) {
        
        return N%2==0;
    }

发布了148 篇原创文章 · 获赞 35 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/flying_all/article/details/103392312