寒假学习之NIM游戏
简要介绍
-
Nim的游戏规则(问题描述):有 N 堆物品,每堆有 M[i] (1 <= i <= N) 个物品,两个人轮流从任意一堆中取任意多的物品,最后取光者获胜。两人都采取最优策略,问:是先手赢还是后手赢 ?
-
定理(亦是结论):如果 M[1] xor M[2] xor M[3] xor …… xor M[N] == 0,那么先手输,否则先手赢。( xor是位运算中的抑或操作 )
自己学习,在网上找到一篇博文学习人家的,自己跟着推导。
推导过程(定理证明):
N堆物品的情况太复杂了,我们首先来考虑一些简单的情况。
-
N = 1时
若 M[1] != 0 (其实也就是其它N - 1堆物品的数量均为0),这种情况下,先手只要一次性把所有的物品取完,那么就赢了。 -
N = 2 时
若M[1] == M[2] && M[1] != 0(其实也就是其它N - 2堆物品的数量均为0),这种情况是先手输。
为什么呢?
不论先手取多少,后手只要在另外的一堆物品中取的物品的数量和他相等,最终肯定会变到情况 1,然后这时该后手取物品,那么后手就赢了。 -
N = 2时
M[1] != M[2] && M[1] != 0 && M[2] != 0, 这种情况是先手赢。因为先手可以把这个状态转移到情况 2 ,然后就赢了。
我们来分析上述四种情况和定理之间的关系。
- 情况1,先手赢。M[1] != 0.
- 情况2,先手输。M[1] xor M[2] == 0.
- 情况3,先手赢。M[1] xor M[2] != 0.
我们再来考虑一下N = 3(就是有3堆物品的数量不为0,其余全为0)的情况。
N == 3
M[1] xor M[2] xor M[3] != 0 && M[1] != 0 && M[2] != 0 && M[3] != 0(就是三个数并非都相等),这种情况下我们一定会有方法到达第 2 种情况的,也就是先手一定赢。
N == 3
M[1] xor M[2] xor M[3] == 0 && M[1] != 0 && M [2] != 0 && M[3] != 0(就是三个数都不相等)。
反证法:假设M[1] == M[2], 那么M[1] xor M[2] == 0,0 xor 任何数是等于这个数的,所以和之前的条件肯定矛盾了。
在这种情况中,要么取一堆,则变为第三种情况,先手就输了;要么变成上面一种情况,则还是输了,则这种情况先手一定输。
我们从N = 2推导到了N = 3,那么只要你不嫌复杂,你肯定能从N = 3推导到N = 4的。我们可以一直推导到N很大的情况。
借鉴:
PS:我并没有讲什么P点和N点。因为我觉得从P点和N点的角度,可能不太是那么容易讲清楚,可能是自身理解的问题吧。在上述的推导过程中,P点即是败点,N点即是胜点。意思就是,若先手的初始位置在N点,则先手肯定有办法赢;若先手的初始位置在P点,则后手肯定会有办法赢的。
其中,还有关于P点和N的三个简单却十分重要的属性:
所有的终结点均是P点。
对于任意的N点,至少会有一种方法进入P点。
无论如何操作,P点只能进入N点。