本着先理论后实践的原则,本文先对“寻找必败态”做出理论上的解释:
要理解这种思想,首先要明白什么叫必败态。说简单点,必败态就是“在对方使用最优策略时,无论做出什么决策都会导致失败的局面”。其他的局面称为胜态,值得注意的是在胜态下做出错误的决策也有可能导致失败。此类博弈问题的精髓就是让对手永远面对必败态。
必败态和胜态有着如下性质:
1、若面临末状态者为获胜则末状态为胜态否则末状态为必败态。
2、一个局面是胜态的充要条件是该局面进行某种决策后会成为必败态。
3、一个局面是必败态的充要条件是该局面无论进行何种决策均会成为胜态
这三条性质正是博弈树的原理,但博弈树是通过计算每一个局面是胜态还是必败态来解题,这样在局面数很多的情况下是很难做到的,此时,我们可以利用人脑的推演归纳能力找到必败态的共性,就可以比较好的解决此类问题了。
下面就通过实际题目来做一些分析:
例1 POJ1740 A New Stone Game
题目大意是:有N堆石子,两人轮流进行操作,每一次为“操作者指定一堆石子,先从中扔掉一部分(至少一颗,可以全部扔掉),然后可以将该堆剩下的石子中的任意多颗任意移到其他未取完的堆中”,操作者无法完成操作时为负。
分析:
只有一堆时先手必胜。
有两堆时若两堆相等则后手只用和先手一样决策即可保证胜利,后手必胜。若不同则先手可以使其变成相等的两堆,先手必胜。
有三堆时先手只用一次决策即可将其变成两堆相等的局面,先手必胜。
有四堆时由于三堆必胜,无论先手后手都想逼对方取完其中一堆,而只有在四堆都为一颗时才会有人取完其中一堆,联系前面的结论可以发现,只有当四堆可以分成两两相等的两对时先手才会失败。
分析到这里,题目好像已经有了一些眉目了,凭借归纳猜想,我们猜测必败态的条件为“堆数为偶数(不妨设为2N),并且可以分为两两相等的N对”。
下面只需证明一下这个猜想。其实证明这样的猜想很简单,只用检验是否满足必败态的三条性质即可。
首先,末状态为必败态,第一条性质符合。
其次,可以证明任何一个胜态都有策略变成必败态(分奇数堆和偶数堆两种情况讨论)。
最后,证明任何一个必败态都无法变成另一个必败态(比较简单)。
由于篇幅关系,这里就不具体证明了,如果有兴趣可以自己试试∶P
接下来的程序就相当简单了,只用判断一下即可。
有些题则比这一题的条件隐蔽许多,例如:
例2 MIPT100 Nim Game -- who is the winner?
题目大意是:有N堆石子,两人轮流取,每次可以从任意一堆中取任意多颗(但至少一颗),谁先取完谁胜。
分析:
还是用按照“手推小数据=〉猜想=〉证明”的模式。
一堆时先手必胜。
两堆时若两堆相等则先手必败,否则先手胜。
三堆的情况就有点复杂了,此时,我们只好借助博弈树来在小范围内求解,从这些解中我们可以看出,对于由两个不同数字构成的两元组,都有且仅有一个三元必败态包含它,这又意味着什么呢?我们定义一个函数F(a,b),表示“包含a,b的三元必败态中的第三数”,则有
F(1,2)=3,F(1,3)=2,F(1,4)=5,F(1,5)=4,F(1,6)=7,F(1,7)=6...
F(2,1)=3,F(2,3)=1,F(2,4)=6,F(2,5)=7,F(2,6)=4,F(2,7)=5...
F(3,1)=2,F(3,2)=1,F(3,4)=7,F(3,5)=6,F(3,6)=5,F(3,7)=4...
..................................................................................
..................................................................................
敏锐的选手马上会发现,这个F(a,b)不就是a XOR(异或) b的结果么?做到这里,答案就在眼前了,‘XOR‘运算恐怕就是本题的关键。
继续求出一些四元必败态,这个性质仍然符合,于是我们猜想,必败态即为“所有堆的石子数XOR运算后结果为零的局面”。这也解释了为什么一堆石子必胜,两堆石子仅在相等时必败。
接下来又是证明:
依旧判断是否符合三条性质。
第一条第三条显然满足,关键就是第二条。
必胜态下,设所有堆石子XOR后结果为N,将其写成二进制,则至少有一堆石子写成二进制后在N的最高位上为一,则可以证明从这堆石子中取可以变成必败态,这里还是留给有兴趣的选手:)
这一题就明显没有上一题轻松了,而且这是个经典问题,结论可以记下来。下面这个例子就是例2的强化版:
例3 POJ1704 Georgia and Bob
题目大意是:一个1*M的棋盘上有N个棋子,初始位置一定,两人轮流操作,每次移动一枚棋子,要求只能向左移且至少移动一格,而且不能到达或经过以前有棋子的格子,谁无法移动棋子就算输。
分析:
乍一看这一题棋子移动还要受其他棋子的限制,好像无法求出通解,但仔细分析会发现别有洞天。
一个棋子每一次向左移的最大步数是固定的,而且随着移动减少,不是和取石子很像么?那么和取石子的区别在哪呢?就在于每一次移动时都会让右边相邻的那颗棋子移动空间变大,这样就和取石子只减不增有所不同了,我们应该怎样解决这个问题呢?
我们并不放弃将其与我们熟悉的取石子对应,但我们将策略做小小的变动:
将棋子从右端向左端每相邻两个分为一对,如果只剩一个就将棋盘左端加一格放一颗棋子与之配对,这样配对后好像和以前没有什么区别,但决策时就方便多了,因为我们大可不必关心组与组之间的距离,当对手移动一组中靠左边的棋子时,我们只需将靠右的那一颗移动相同步数即可!同时我们把每一组两颗棋子的距离视作一堆石子,在对手移动两颗棋子中靠右的那一颗时,我们就和他玩取石子游戏,这样就把本题与取石子对应上了。
本例说明有许多模型看似复杂,但经过一些巧妙的变换,便可以转化成一些我们熟悉的模型,同时也充分体现了博弈的灵活。
如果说前面的例子是介绍这种思想的运用的话,下面的方法就是讲这种思路的优越性了,因为这一题并不是走的“手推小数据=〉猜想=〉证明”的老路,而是直接利用性质推导必败条件。
例4
url=http://acm.pku.edu.cn/JudgeOnline/showmessage?message_id=4163]POJ1067
取石子游戏[/URL]
题目大意是:......题目本来就是中文的-_-b。
分析:
刚拿到这一题时,我不加思索的猜想必败态为“两堆石子的数目是2:1”,用性质判定:第一条显然符合,第二条分情况讨论每一种“胜态”都有一种固定的方法变成“必败态”,再看第三条,设第一堆有N颗,第二堆有2*N颗,则无论怎样拿都无法让第二堆保持为第一堆的两倍。证毕。
本以为此题就这么简简单单完了,但是我突然发现,当第一堆2颗,第二堆4颗时,从第二堆中取出3颗石子的话第二堆的确无法保持为第一堆的两倍,但第一堆会变成第二堆的两倍,基于此,整个猜想被彻底推翻。
于是我反转思路,干脆从性质入手。
我们令必败二元组为(a,b)形式,并令a<b。
根据性质三,有这样两个推论:
推论一:对于任意两个的必败二元组(a1,b1),(a2,b2),有a1<>a2,b1<>b2,a1<>b2,a2<>b1。
推论二:对于任意两个的必败二元组(a1,b1),(a2,b2),有b1-a1<>b2-a2。
利用性质和该推论,我们证明如下结论:“将必败二元组按首元为关键字排序,每个必败二元组中首元为未在前面的必败二元组中出现的最小正整数,并且第N组中两个数差为N”。
利用数学归纳法证明:
第一组为(1,2),满足题意。
若前N组满足题意,则有:
设为在前N组中出现的最小正整数为M,则对于二元组(M,M+N+1)有:
如果从数量为M的堆中取了石子,不妨设变成了(K,L),则L-K>N,这样就有一个包含K,且不与前面N组任何一组相同的二元组,根据推论一,这个二元组一定不是必败二元组。
如果只从数量为M+N+1的堆中取,不妨设剩下K颗,又分三种情况:
K>M,则N+1>K-M>0,根据推论二,这个二元组一定不是必败二元组。
K=M或0,显然不是必败二元组。
0<K<M,则(K,M)为包含K,且不与前面N组任何一组相同的二元组,根据推论一,这个二元组一定不是必败二元组。
综上,根据性质三,(M,M+N+1)为必败二元组,又根据排序的法则,(M,M+N+1)一定是数列的第(N+1)项。证毕。
这样利用性质和性质得出的推论,此题的必败态也完美的找出了。
从上面的例子可以看出,利用寻找必败态的思路解题对猜想和数学证明的能力要求很高,对思维的训练有很大好处,同时编程复杂度相当低,也不失为一种好的解题方法。