尼姆博弈

我们在分析的过程中需要把n堆石子的个数都用二进制表示,例如上面1,1, 2, 3的例子对应的就是:

0    1

0    1

1    0

1    1

 

1. 先从最简单的两堆石子(a1, a2)看起,当a1 = a2时,两排二进制数字一模一样,按位异或之后得到0,先手必输。

当a1 > a2时(a1 < a2的情况类似),不妨假设为(6,5),表示成二进制为:

1    1    0

1    0    1

按位异或后得到3 > 0,这个时候先手只要从a1中拿走部分(a1-a2),使得a2 = a1就可以必胜了。

 

两堆的时候先手拿走几个使得他们的异或结果为0很显然,那么三堆该怎么处理呢?

 

2. 当有三堆石子(a1, a2, a3)时,我们还是从例子说起

(1, 2, 3)表示成:

0    1

1    0

1    1

按位异或结果为0,结论是先手必输,我们现在来枚举一下解法,看看先手是否有这样的绝对劣势。

(1)如果先手选择a1,只能拿走1个,剩下2和3,后手将两堆都变成2,先手必输;

(2)如果先手选择a2,那么他肯定不能全部拿走,因为那样的话局势跟1一样,所以他可以选择拿走1个,然后剩余1,1,3,后手选择a3拿走3个,剩下1,1,先手必输;

(3)如果先手选择a3,那么首先他不能全拿走,理由同上。如果他拿走1个,变成1,2,2,后手选择a1全拿走,剩下2,2,先手必输;

如果先手拿走2个,变成1,2,1,后手选择a2全拿走,剩下1,1,先手必输;

 

那如果是(1, 2, 4)呢?他们的按位异或运算结果不为0,先手应该怎么做才能使得拿走几个后这些数字异或值为0,这样后手就具有绝对劣势了。

0    0    1

0    1    0

1    0    0

异或结果k = 111B = 7,k中为1的位表示3堆石子数目异或运算时那位肯定有个1是单独的,为了使得整体异或为0,我们需要给k表示的所有位为1的那位再配一个1,举个例子来说的话就是,如果异或结果k是

8 7 6 5 4 3 2 1

1 0 1 0 0 1 0 1

其中第1,3,6,8位为1表示,这些位还缺一个1才能异或的时候得到全0。很显然给k^k结果是0,但是这样是增加了k个石子啊,现在要减少石子,使得总的异或结果为0。

 

还是上面(1, 2, 4)的例子,如果我们选择a3堆,把(1    0    0)变成(0    1    1)(即从a3堆中拿走1个石子)是不是异或结果就为0了,这和之前的异或结果k(1    1    1)有什么关联呢?

(1    0    0)把第一位取反,然后其余位与k异或,也就是(1    0    0)^(1    1    1)=(0    1    1)。

那么是不是任选一堆哪来跟k异或一下就得到我们想要的结果呢?(0    0    1)^(1    1    1)=(1    1    0)。与另外的两堆异或,结果果然是0,但是不幸的是这不是一个有意义的解,因为这堆的1个石子变成了6个,哪里偷来5个石子?选a2堆结果也是一样没有意义。

为什么只有选择a3堆进行与k的异或是有意义的呢?这里的a3是根据什么原则选择的呢?

原则只有一个,选择k的最高位对应为1的那个数字,这里k的最高位为第三位,该位为1的只有第三堆了。之所以这个选择有效,是因为经过异或运算后,这位的1变成0,之后可能变成1的位都比该位低,所以最后的数字肯定比与k异或之前要小。

 

综上,对于(1, 2, 4),先手选择a3堆,拿走1个石子,变成(1,2,3),后手必输。

 

3. 现在来推广上面的情况,假设有n堆石子,我们怎么做呢?

 

先说结论,如果n堆石子数目的二进制按位异或结果为0,那么先手必输,因为不管先手怎么选择,异或结果都会不为0,然后后手将其恢复为0即可。终态是所有堆石子均为0,异或结果为0,这时先手没有任何选择,输掉游戏。

如果n堆石子数目的按位异或结果不为0,那么先手只要根据下面的策略拿走部分石子,使得异或结果为0,那么根据上面那条结论,后手必输。

 

当n堆石子数目异或结果为k时,先手只需要从n堆中选择k的最高位对应的那位为1的那堆石子,不妨设为ai,然后将ai变成ai^k,也就是拿走(ai - (ai^k))个石子就可以了。

这里ai是肯定至少存在一个的,因为不然的话异或结果k的这位不可能成为1。当然可能会存在多个满足这样条件的ai,我们只需要随便选择一个即可。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值