Ferguson博弈
清空/分割游戲也叫做Ferguson博弈。
進行游戲需要用到兩個盒子,在游戲的開始,第一個盒子中有n枚石子,第二個盒子中有m個石子(n, m > 0)。參與游戲的
兩名玩家輪流執行這樣的操作:清空一個盒子中的石子,然后從另一個盒子中拿若干石子到被清空的盒子中,使得最后兩個
盒子都不空。當兩個盒子中都只有一枚石子時,游戲結束。最后成功執行操作的玩家獲勝。找出游戲中所有的P位置。
結論:對于一個位置(x, y)來說,如果x, y中有一個偶數,那么(x, y)是N(必勝)位置。如果x和y都是奇數,那么
(x,?y)是P位置(必敗),可以用數學歸納法證明。
證明:
證明結論:(x,y)至少一偶時,先手勝;都為奇時,先手敗
證明:
(x,y)=(1,1)時是先手必敗態,下對max(x,y)>1進行歸納
1、當max(x,y)=2時,即(x,y)=(1,2)或(2,1)或(2,2),先手留下一個2分為(1,1),先手獲勝。
即當max(x,y)=2時結論成立。
2、假設max(x,y)<k時結論都成立,現證max(x,y)=k時結論成立。
若(x,y)中有一個偶數(設為a),先手將另一個清空,把偶數a分為兩個奇數b和c,由于b、c<a 小于等于 k,即
max(b,c)<k,由假設,在(b,c)位置上后手作為新先手必敗,故先手勝。
若(x,y)都為奇數,先手只能保留一個奇數并將其分解為一奇a一偶b,由于max(a,b)<max(x,y)=k,由假設,在(a,b)位
置上后手作為新先手必勝,故先手敗。
經典題目:http://acm.hdu.edu.cn/showproblem.php?pid=2147
題目:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3714
題意:本題與清空/分割游戲不同的是,每次清空球較少的那個盒子,而清空/分割游戲是清空任意一個盒子,不管球的個數多少,其它條
件都相同。
分析:本題就是找規律,可以發現就是判斷n+1是否是2的整數次冪,那么用(n & ( n + 1 )) == 0來判斷就行了。
暴力程序:
#include <iostream> #include <string.h> #include <stdio.h>using namespace std; const int N = 105;bool dp[N][N]; bool vis[N][N];bool dfs(int n,int m) {if(n == 1 && m == 1) return 0;if(vis[n][m]) return dp[n][m];for(int i=1; i<=n/2; i++){dp[n-i][i] = dfs(n-i,i);vis[n-i][i] = 1;}for(int i=1; i<=n/2; i++)if(!dp[n-i][i]) return 1;return 0; }int main() {memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));for(int i=1;i<65;i++)cout<<dfs(i,1)<<" ";cout<<endl;return 0; }
結論:如果(n & (n + 1)) == 0,那么先手敗,否則先手勝。
#include <iostream> #include <string.h> #include <stdio.h>using namespace std;int main() {int n;while(cin>>n){if(n == 0) break;if((n & (n + 1)) == 0) puts("Bob");else puts("Alice");}return 0; }
總結
以上是生活随笔為你收集整理的Ferguson博弈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 圆的反演变换
- 下一篇: Chomp!博弈(巧克力游戏)