1.巴斯博弈(Bash Game):有一堆物品共n个,两名游戏者轮流从这堆物品中取物,游戏规则为每次至少取一个,最多取m个。最后将物品取完的player获胜。
分析:当 n % ( m+1 ) != 0 时,先取物品的游戏者必胜,取法为第一次先取走 n % ( m+1 ) 个物品,以后每个回合保持两个游戏者拿走的物品和为 m+1 即可。
变相玩法:两人轮流报数,每次至少报一个,最多报十个,谁可以报到100则获胜。
2.威佐夫博弈(Wythoff Game):有两堆物品各有若干个,两名游戏者轮流从某一堆中取物或同时从两堆中取同样数目的物品,游戏规则为每次至少取一个物品,现有物品数目范围内不设上限,最后将物品取完的player获胜。
分析:假设现有player甲和player乙,其中甲先取。如果甲面对(0,0),那么甲已经输了。同理局势分别为(1,2)、(3,5)、(4,7)、(6,10)时,甲最终也会输,我们将这些局势称为奇异局势,也即当先取者面临奇异局势时结果是取物失败。经分析我们可以看出,若设( a0 , b0 ) = ( 0 , 0 ), 则ak是未在前面出现过的最小自然数,bk=ak+k.
对于任给的一个局势(a,b),可利用如下公式判断其是否为奇异局势:ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,...,n 方括号表示取整函数)。于是可先求出 k = bk-ak. 若ak ==[k*(1+√5)/2],那么( a , b )就是奇异局势。
3.尼姆博弈(Nimm Game):有三堆物品各若干个,两名游戏者轮流从某一堆物品中取任意多个,游戏规则为每次至少取一个,现有物品数目范围内不设上限,最后将物品取完的player获胜。
分析:对于任何奇异局势(a,b,c),都有a^b^c=0,此时,先取物的player将失败。为了将 非奇异局势(a,b,c)(a<b<c)转换为奇异局势,我们只需将c变为a^b,也即从c中减去c-(a^b)。
(注:以上游戏均假设两名游戏者每个回合采取最好的游戏策略。)
实例(POJ1067)
//Time:0ms //Memory:144k //Date:2015.03.23 #include <stdio.h> #define GoldenRatio (1+sqrt(5.0))/2.0 int Wythoff(int a,int b){ int k,temp; if(a>b){ temp=a; a=b; b=temp; } k=b-a; if(a==(int)(k*GoldenRatio)) return 0; else return 1; } void main(){ int a,b; while(scanf("%d%d",&a,&b)!=EOF) printf("%d\n",Wythoff(a,b)); }