博弈是有一种很有意思的游戏,就是有物体若干堆,可以是火柴棍或是围棋子等等均可。两个人轮流从堆中取物体若干,规定最后取光物体者取胜。这是我国民间很古老的一个游戏,别看这游戏极其简单,却蕴含着深刻的数学原理。下面我们来分析一下要如何才能够取胜。
有一堆 n n n 个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取 m m m 个。最后取光者得胜。
显然,如果 n = m + 1 n=m+1 n=m+1,那么由于一次最多只能取 m m m 个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。
因此我们发现了如何取胜的法则:如果 n = ( m + 1 ) r + s n=(m+1)r+s n=(m+1)r+s,( r r r 为任意自然数, s ≤ m s\leq m s≤m),那么先取者要拿走 s s s 个物品,如果后取者拿走 k k k( ≤ m \leq m ≤m)个,那么先取者再拿走 m + 1 − k m+1-k m+1−k 个,结果剩下 ( m + 1 ) ( r − 1 ) (m+1)(r-1) (m+1)(r−1) 个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下 ( m + 1 ) (m+1) (m+1) 的倍数,就能最后获胜。
这个游戏还可以有一种变相的玩法:两个人轮流报数,每次至少报一个,最多报十个,谁能报到 100 100 100 者胜。
有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
这种情况下是颇为复杂的。我们用 ( a k , b k ) (a_k,b_k) (ak,bk) ( a k ≤ b k , k = 0 , 1 , 2 , … , n ) (a_k \leq b_k, k=0,1,2,\ldots,n) (ak≤bk,k=0,1,2,…,n) 表示两堆物品的数量并称其为局势,如果甲面对 ( 0 , 0 ) (0,0) (0,0),那么甲已经输了,这种局势我们称为奇异局势。前几个奇异局势是: ( 0 , 0 ) (0,0) (0,0)、 ( 1 , 2 ) (1,2) (1,2)、 ( 3 , 5 ) (3,5) (3,5)、 ( 4 , 7 ) (4,7) (4,7)、 ( 6 , 10 ) (6,10) (6,10)、 ( 8 , 13 ) (8,13) (8,13)、 ( 9 , 15 ) (9,15) (9,15)、 ( 11 , 18 ) (11,18) (11,18)、 ( 12 , 20 ) (12,20) (12,20)。(统计小规模数据)
可以看出, a 0 = b 0 = 0 a_0=b_0=0 a0=b0=0, a k a_k ak 是未在前面出现过的最小自然数,而 b k = a k + k b_k= a_k + k bk=ak+k。发现规律,得到猜想。
奇异局势有如下三条性质:
由于 a k a_k ak 是未在前面出现过的最小自然数,所以只需证明 b k b_k bk 不会出现在前面的奇异局势中即可。由于 a k > a k − 1 a_k > a_{k-1} ak>ak−1,而 b k = a k + k > a k − 1 + ( k − 1 ) = b k − 1 > a k − 1 b_k= a_k + k > a_{k-1} + (k-1) = b_{k-1} > a_{k-1} bk=ak+k>ak−1+(k−1)=bk−1>ak−1。所以性质 1 成立。(从第 0 项到第 k k k 项, a k a_k ak 是递增的;由于 b k = a k + k b_k=a_k+k bk=ak+k,所以 b k b_k bk 也是递增的。)
事实上,若只改变奇异局势 ( a k , b k ) (a_k,b_k) (ak,bk) 的某一个分量,那么另一个分量不可能在其他奇异局势中(性质 1),所以必然是非奇异局势。如果使 ( a k , b k ) (a_k,b_k) (ak,bk) 的两个分量同时减少,则由于其差不变,且不可能是其他奇异局势的差(因为 k k k 是递增的,所以每个奇异局势对应唯一一个差),因此也是非奇异局势。
假设面对的局势是 ( a , b ) (a,b) (a,b) (设 a ≤ b a\leq b a≤b,否则先交换 a a a 和 b b b),若 b = a b=a b=a,则同时从两堆中取走 a a a 个物体,就变为了奇异局势 ( 0 , 0 ) (0,0) (0,0);如果 a = a k a=a_k a=ak, b > b k b>b_k b>bk,那么,取走 b − b k b-b_k b−bk 个物体,即变为奇异局势;如果 a = a k a=a_k a=ak, b < b k b
从如上性质可知,两个人如果都采用正确操作,那么面对非奇异局势,先拿者必胜;反之,则后拿者取胜。
给定一个局势 ( a , b ) (a,b) (a,b),如何判断它是否为奇异局势呢?我们可以使用以下公式:
a k = ⌊ k ( 1 + 5 ) / 2 ⌋ , b k = a k + k ( k = 0 , 1 , 2 , … , n ) a_k = \left\lfloor k\left(1+\sqrt{5}\right)/2 \right\rfloor, \quad b_k = a_k + k \quad (k=0,1,2,\ldots,n) ak=⌊k(1+5)/2⌋,bk=ak+k(k=0,1,2,…,n)
其中, ⌊ x ⌋ \lfloor x \rfloor ⌊x⌋ 表示取整函数。有趣的是,公式中出现了黄金分割数 ( 1 + 5 ) / 2 = 1.618 … (1+\sqrt{5})/2 = 1.618\ldots (1+5)/2=1.618…,因此由 a k a_k ak 和 b k b_k bk 组成的矩形近似为黄金矩形。我们可以先求出 j = ⌊ a ( 5 − 1 ) / 2 ⌋ j = \lfloor a(\sqrt{5}-1)/2 \rfloor j=⌊a(5−1)/2⌋,然后判断:
另一种判断方法是:给定 ( a , b ) (a,b) (a,b)( a < b aa<b),先计算 k = b − a k = b - a k=b−a,然后根据 k k k 计算 a k a_k ak 和 b k b_k bk。如果 a k = a a_k = a ak=a 且 b k = b b_k = b bk=b,那么 ( a , b ) (a,b) (a,b) 是奇异局势,否则不是。
有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。这种情况最有意思,它与二进制有密切关系,我们用 ( a , b , c ) (a,b,c) (a,b,c) 表示某种局势,首先 ( 0 , 0 , 0 ) (0,0,0) (0,0,0) 显然是奇异局势,无论谁面对奇异局势,都必然失败。第二种奇异局势是 ( 0 , n , n ) (0,n,n) (0,n,n),只要与对手拿走一样多的物品,最后都将导致 ( 0 , 0 , 0 ) (0,0,0) (0,0,0)。仔细分析一下, ( 1 , 2 , 3 ) (1,2,3) (1,2,3) 也是奇异局势,(我先拿之后,)无论对手如何拿,接下来都可以变为 ( 0 , n , n ) (0,n,n) (0,n,n) 的情形。
计算机算法里面有一种叫做按位模 2 加,也叫做异或的运算,我们用符号 ( + ) (+) (+) 表示这种运算。这种运算和一般加法不同的一点是 1 + 1 = 0 1+1=0 1+1=0。先看 ( 1 , 2 , 3 ) (1,2,3) (1,2,3) 的按位模 2 加的结果:
1 = 二进制 01 2 = 二进制 10 3 = 二进制 11 1 (+) 2 (+) 3 = 0 (注意不进位) 1 = \text{二进制 } 01 \\ 2 = \text{二进制 } 10 \\ 3 = \text{二进制 } 11 \\ 1 \text{ (+) } 2 \text{ (+) } 3 = 0 \text{ (注意不进位)} 1=二进制 012=二进制 103=二进制 111 (+) 2 (+) 3=0 (注意不进位)
对于奇异局势 ( 0 , n , n ) (0,n,n) (0,n,n) 也一样,结果也是 0 0 0。任何奇异局势 ( a , b , c ) (a,b,c) (a,b,c) 都有 a (+) b (+) c = 0 a \text{ (+) } b \text{ (+) } c = 0 a (+) b (+) c=0。
如果我们面对的是一个非奇异局势 ( a , b , c ) (a,b,c) (a,b,c),要如何变为奇异局势呢?假设 a < b < c a < b < c a<b<c,我们只要将 c c c 变为 a (+) b a \text{ (+) } b a (+) b 即可,因为有如下的运算结果:
a (+) b (+) ( a (+) b ) = ( a (+) a ) (+) ( b (+) b ) = 0 (+) 0 = 0 a \text{ (+) } b \text{ (+) } (a \text{ (+) } b) = (a \text{ (+) } a) \text{ (+) } (b \text{ (+) } b) = 0 \text{ (+) } 0 = 0 a (+) b (+) (a (+) b)=(a (+) a) (+) (b (+) b)=0 (+) 0=0
要将 c c c 变为 a (+) b a \text{ (+) } b a (+) b,只要从 c c c 中减去 c − ( a (+) b ) c-(a \text{ (+) } b) c−(a (+) b) 即可。