只有一堆n个石子,两个人轮流从这堆石子中取石子,规定每次至少取一个,最多取m个,最后取完的人获胜。
其中上述的情况1和3可以合并,故:
当 n % (m+1) = 0时,后手必胜。当 n % (m+1) != 0时,先手必胜。有一堆个数为n的石子,游戏双方轮流取石子,满足:
先手不能再第一次把所有石子取完; 之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间,包括1和对手取的石子数的2倍。 取最后石子的人为赢家。先说结论: 当且仅当n不是Fibonacci数时,先手必胜。换句话说,先手必败构成Fibonacci数列。
证明需要前置技能,“Zeckendorf定理”(齐肯多夫定理),其表述为:任何正整数可以表示为若干个不连续的Fibonacci数之和。
具体证明在这篇博文中给出,有兴趣的读者可以自行学习。
有两堆各若干个石子,两个人轮流从某一堆或者两堆中取同样多的物品,规定每次至少取一个,多着不限,最后取完石子的人获胜。
设这两堆石子分别有(A,B)个,并且A<=B。我们先来看一下先手必败的局势。
(0,0) 先手必败,很明显他没得取了。(1,2) 先手必败。具体分析一下,先手有以下几种取法: 取第一堆的1个,后手取走第二堆的2个获胜。 从第一堆第二堆各取1个,后手取走第二堆剩下的1个获胜。 取第二堆的1个,后手从第一堆第二堆各取1个获胜。 取第二堆的2个,后手取走第一堆的1和获胜。 综上所述,先手必败。(3,5) 先手必败。 首先可以明确的一点是,先手不能把任意一堆取完,如果取完显然必败。 先讨论先手从第一堆中取的情况 先手可以从第一堆中取1个,后手从第二堆中取4个,转化为(1,2),先手必败。 先手可以从第一堆中取2个,后手从第二堆中取3个,转化为(1,2),先手必败。 再讨论先手从第二堆中取的情况 先手可以从第二堆中取1个,后手从两堆中各取2个,转化为(1,2),先手必败。 先手可以从第二堆中取2个,后手从两堆中各取3个,转化为(0,0),先手必败。 先手可以从第二堆中取3个,后手从两堆中各取1个,转化为(1,2),先手必败。 先手可以从第二堆中取4个,后手从第一堆中取2个,转化为(1,2),先手必败。 接着讨论先手从两堆中取的情况 先手可以从两堆中各取1个,转化为(2,4),此时情况较多 后手足够聪明,他从第二堆中取了1个,转化为(2,3),先手也足够聪明,他为了不直接输掉,从第一堆中取了1个(其他取法直接输掉了),转化为(1,3),此时后手从第二堆中取1个,转化为(1,2),先手必败。 先手可以从两堆中各取2个,后手从第二堆中取一个,转化为(1,2),先手必败。 综上所述,先手必败。其他的先手必败局势 (4,7),(6,10),(8,13),(9,15),(11,18).
我们将先手必败局势的集合,称为奇异局势。
我们可以发现,将所有奇异局势按照第一堆的石子的数目从小到大排列,每个奇异局势的差值是自然数列。 进一步观察发现,对于一个奇异局势(A,B), A = 下取整[ (B-A) * 1.618 ],更准确的说,1.618 = (sqrt(5) + 1) / 2.
为什么会是这样的? 具体的证明涉及到Betty的定理,有兴趣的读者可以百度,这里不再赘述。
有三堆石子, 每堆有若干个,两个人轮流从某一堆中任取石子,每次至少取一个,多者不限,最后取完者获胜。
用(A,B,C)来表示某一特定局势,同时规定A<=B<=C。奇异局势表示先手必败。
显然(0,0,0)是奇异局势。(0,n,n)是奇异局势,当先手拿走s个石子时,我们对应拿走s个石子,最终转化为(0,0,0)。(1,2,3)也是奇异局势,无论先手如何取,我们都可以转化为(0,n,n)的局势。对于一个奇异局势(A,B,C),我们可以发现,A(XOR)B(XOR)C = 0。 下面一条需要的前置技能 设有数字a,b,a(XOR)b(XOR)(a(XOR)b) = (a(XOR)a)(XOR)(b(XOR)b) = 0 对于一个非奇异局势(A,B,C),我们只需要将C转化为(A(XOR)B)即可,而将C转化为(A(XOR)B)的操作为,C = C-(A(XOR)B)即可。
注:
异或在C语言中的符号为^。对于此情景来说,可以推广到N堆石子,奇异局势的条件为A1(XOR)A2(XOR)A3(XOR)……AN(XOR) = 0。A(XOR)B(XOR)B = A,可推广到N个变量,A1(XOR)A2(XOR)A3(XOR)……(XOR)AN(XOR)AN(XOR)AN-1(XOR)……(XOR)A3(XOR)A2 = A1;SG函数为计算博弈状态的函数,当SG[X] = 0时,说明先手必败。 为了求解SG函数,首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。 对于任意状态 x , 定义 SG(x) = mex(S),其中 S 是 x 后继状态的SG函数值的集合。如 x 有三个后继状态分别为 SG(a),SG(b),SG(c),那么SG(x) = mex{SG(a),SG(b),SG(c)}。 这样 集合S 的终态必然是空集,所以SG函数的终态为 SG(x) = 0,当且仅当 x 为必败点P时。
说起来很抽象,举一个具体的例子来说明一下。
有1堆n个的石子,每次只能取{ 1, 3, 4 }个石子,先取完石子者胜利,那么各个数的SG值为多少?
SG[0] = 0(显然没有石子可取时必败); f[] = {1,3,4}(表示每次取有3中方案,取1个,取3个,取4个);
当石子x = 1时,可以取走1-f{1}个石子,SG[1] = mex(SG[1-1]) = mex(0) = 1; 当石子x = 2时,可以取走2-f{1}个石子,SG[2] = mex(SG[2-1]) = mex(1) = 0; 当石子x = 3时,可以取走3-f{1,3}个石子,SG[3] = mex(SG[3-1],SG[3-3]) = mex(0,0) = 1; 当石子x = 4时,可以取走4-f{1,3,4}个石子,SG[4] = mex(SG[4-1],SG[4-3],SG[4-4]) = mex(1,1,0) = 2;
以此类推…
我们可以打出SG函数的表,根据表来判断是先手必胜还是先手必败。
