生活日用算法——NIM博弈

故事还是得从笔者某次去ktv说起。席间见到某汉子拿出15个色子,分成3,5,7三组,开始和妹子按照以下规则玩耍:

1、每次可以从任意一组中取任意个色子

2、取到最后一组的人赢

任意先后手,大多是某汉子一直赢,然后妹子一直喝,然后。。。

 

故事背景大概就是这样,回去后我尝试用枚举的方式去寻找必胜策略。大概可以等到以下形式的必胜组合2,2;3,3;4,4;5,5;1,2,3;1,4,5等,但转念一想如果玩的多了妹子也背下了必胜组合,我方就必须得实时更新自己脑海中的必胜组合,这不符合我们一个理科生的世界观。于是仔细百度了一下此类问题,发现原来早走定论,就是一个MIN博弈而已。

 

先来讲下异或运算的概念,简单来讲,设a不等于b,则a⊕b=1,a⊕a=0,b⊕b=0,b⊕a=1,文字表述如下:如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

 

接下来我们回到问题本身,如何在此游戏中保持必胜,简单来讲,对于取到最后一组的人赢的情况,我们只需保证,每次自己取完,使得各组的二进制异或运算结果为0即可。或者说,保证各组转化二进制后,各位数上的1的总量为偶数

简单证明如下:

1、首先当我方取掉最后一组取得胜利后,剩余情况符合上述情况,简称胜利态好了。

2、胜利态中的任意操作后,总会转化为非胜利态。总量减少,被移动的那一组一定有二进制1变0,那么这一位的1总量偶数变奇数。

3、由胜利态转换来的非胜利态,一定可以通过一次移动,再转换为胜利态:

因为无论对方移动那一堆,其移动后消失的二进制最大值,一定有另一堆具备。。否则异或运算不会为0。因为a与任意个0进行异或运算,结果一定为1此时,把对应堆最大值取掉,其余堆对应移动即可。

举例说明下,比如,现在有三堆为1+2;1+4;2+4这种情况,对方选择从第三堆中移除3个, 此时可以此变换转变为4-1,即110->11,可以发现变化的位置为第三位和第一位。我么只要找到4对应存在的位置,即2+4,二进制110,
然后只要对他的第三位和第一位取反,变成011即可。

实际操作中,如果发现你先手总是赢,你给她摆一个胜利态让她先手,就可以继续套路了,比如5,9,12

 

为了增加趣味性,可以把规则变为取到最后一个的输,这时候问题就转化为了反NIM问题

此问题的必胜态与必输态如下:

1、如果剩余所有堆均为1,则根据堆总数为偶数为必胜态。

2、如果剩余堆的中只有一堆不为1,则各组的二进制异或运算结果必不为0,则此状态为必输态。

3、如果剩余堆中有多余一堆不为1,则各组的二进制异或运算结果为0为必胜态。

 

证明如下:

在对于两组以上,我方保持3状态,对方只能做出非3状态,我方可转换为3

只剩两组非1时,我方保持3状态,对方最终将只能转变为2状态。详解如下:

只有两堆的数字非1时,我们分为为1的堆总数是奇数或者偶数来探讨。
如果1的数量为偶数,非1堆数字一定相等。此时对方取数量为1的堆,我方也取数量为1的堆;
对方取数量非1的堆,对方取几个我方取几个即可维持此状态。最后可以保证只剩下偶数个1。

如果1的数量为奇数,非一堆保持一个比另一个多1。此时对方取数量为1的堆,我方也取数量为1的堆;
对方取数量非1的堆,对方取几个我方取几个即可维持此状态。

对方如果在两堆非1为2,3之前取光一堆或取一堆只剩下1个,则对方进入必输态2
两堆非1变成2,3之后。对方如果从2取必定进入必输态2
两堆非1变成2,3之后。对方如果从3取,取2或3依旧进入必输态2
两堆非1变成2,3之后。对方如果从3取1,我们只要取走一个1,则进入状态3,我方必胜。

 

总结来讲,非1堆大于1时,保持与NIM博弈同种策略即可

 

玩法继续多样性,还可以规定每次最多只能去k个,此时的必胜态是把各堆转化为二进制,是取二进制1的总数mod k为0即可。证明略。

 

posted @ 2019-05-10 14:10  豆豆323  阅读(268)  评论(0编辑  收藏  举报