生活日用算法之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与2,2。。对方取2,2任意,则会变为必胜态3状态,
后者终转变成2,3与奇数个1,此是对方取一个1,则我方取3->2编程上述状态,对方取3->2我方取1.其余取法对方会呈现必输态2

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

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

猜你喜欢

转载自www.cnblogs.com/fbw-gxy/p/10844129.html