愛麗絲和鮑勃一起玩遊戲,他們輪流行動。愛麗絲先手開局。
最初,黑板上有一個數字 N 。在每個玩家的回合,玩家需要執行以下操作:
選出任一 x,滿足 0 < x < N 且 N % x == 0 。
用 N - x 替換黑板上的數字 N 。
如果玩家無法執行這些操作,就會輸掉遊戲。
只有在愛麗絲在遊戲中取得勝利時才返回 True,否則返回 false。假設兩個玩家都以最佳狀態參與遊戲。(重點)
輸入:2
輸出:true
解釋:愛麗絲選擇 1,鮑勃無法進行操作。
輸入:3
輸出:false
解釋:愛麗絲選擇 1,鮑勃也選擇 1,然後愛麗絲無法進行操作。
解法:
思維是動態規劃,N減去一個符合要求的i,看N-i是什麼,那結果就是與N-i相反
public boolean divisorGame0(int N) {
if(N<2)return false;
if(N==2)return true;
if(N==3)return false;
boolean dp[]=new boolean[N+1];
for(int n=4;n<=N;n++){
for(int i=1;i<=n/2;i++){
if(n%i==0&&dp[n-i]==false){
dp[n]=true;
break;
}
}
}
return dp[N];
}
更加深入理解,由於要求每個人都是聰明的,所以每個人每次都會選擇對自己最有利的數值,所以以5講解(結果是false))
A:N=5-----i只能取1---->N=4
B:N=4---i可以取1,2----》N=3,2
A:N=3--->A輸了
N=2--->A贏了,雖然這種方式A贏了,但B也是聰明的,不可能在上一步選擇i=2,所以,上一步B選擇i=1最終A還是輸了。
》》》》》》博弈方案都是聰明的,只能靠N本身和誰先來這兩個規則,來定輸贏,
可以看出 當N爲奇數,每次每個人都會選擇i=1,最終A還是輸,套路,可以拿這個去套路比人。
實際上,最簡單的理解就是偶數贏,奇數輸。
public boolean divisorGame(int N) {
return (N%2==0);
}