引言
本文主要介绍acm中有关博弈论的基础知识点,意在梳理博弈论学习的总体框架与基本逻辑,使读者和作者都能够对博弈论的思维方式有更深入的理解。
博弈论:
巴什博奕
经典巴什博奕
问题:有两个绝顶聪明的人在玩取石子游戏,假设最初有n个石子,每人可以轮流取1~m范围内的石子,如果没有石子可取就失败,问先手胜还是后手胜。
巴什博奕属于博弈论中最基础的问题,但从该问题我们往往能够扩展得出许多研究博弈论的基础方法。
从特殊到一般:如果不清楚如何解决这个问题,不妨考虑最简单的情况。
局面一:当
n
≤
m
\mathbf{n\le m}
n≤m的时候,显然先手可以直接取走所有的石子,先手必胜。
局面二:当
n
=
m
+
1
\mathbf{n=m+1}
n=m+1的时候,先手无法一次性取完所有石子,但是先手取了1~m颗石子以后石子数量就满足
n
≤
m
\mathbf{n\le m}
n≤m,这是局面一的情况,根据局面一的结论,局面一的先手必胜,也就是局面二的后手必胜,所以局面二的先手必输。
局面三:当
m
+
1
<
n
≤
m
+
1
+
m
\mathbf{m+1<n\le m+1+m}
m+1<n≤m+1+m的时候,先手一定可以将石子取成
n
=
m
+
1
\mathbf{n=m+1}
n=m+1的情况,也就是说让后手遇到了局面二的情况,根据上文关于局面二的讨论可以知道局面二的先手必输,因此局面三的后手必输,因此局面三的先手必赢。
局面四:当
n
=
m
+
1
+
m
+
1
\mathbf{n=m+1+m+1}
n=m+1+m+1的时候,由于无论如何先手也只能将石子取为
m
+
1
<
n
≤
m
+
1
+
m
\mathbf{m+1<n\le m+1+m}
m+1<n≤m+1+m的局面,也就是局面三,同理根据局面三的结论可以知道局面四的先手必输。
…
局面n:…
归纳与总结:很容易发现一个规律,当
(
m
+
1
)
∣
n
\mathbf{(m+1)|n}
(m+1)∣n,先手必输,如果想直接证明这一点,不妨设
n
=
k
∗
(
m
+
1
)
+
r
(
r
<
m
+
1
)
\mathbf{n=k*(m+1)+r\quad (r<m+1)}
n=k∗(m+1)+r(r<m+1),当
r
≠
0
\mathbf{r\ne 0}
r=0先手可以取r个石子使得局面变为
n
=
k
∗
(
m
+
1
)
\mathbf{n=k*(m+1)}
n=k∗(m+1),而后手只能将局面变为
n
=
(
k
−
1
)
∗
(
m
+
1
)
+
r
′
(
r
′
<
m
+
1
)
\mathbf{n=(k-1)*(m+1)+r'\quad (r'<m+1)}
n=(k−1)∗(m+1)+r′(r′<m+1),然后先手依然可以拿掉
r
′
\mathbf{r'}
r′个石子使得局面变为
n
=
(
k
−
1
)
∗
(
m
+
1
)
\mathbf{n=(k-1)*(m+1)}
n=(k−1)∗(m+1)…以此类推,直到最后先手拿掉石子使得局面变为
n
=
0
∗
(
m
+
1
)
\mathbf{n=0*(m+1)}
n=0∗(m+1)取得胜利。
因此可以得出关于巴什博奕的结论:当
(
m
+
1
)
∣
n
\mathbf{(m+1)|n}
(m+1)∣n先手必败,否则先手必胜。
巴什博奕扩展
扩展一:在经典巴什博奕的基础上,假设拿走最后一颗石子的一方输掉,那么结果如何?
拿走最后一颗石子的一方输掉,可以转化为拿走前n-1颗石子中的最后一颗的一方胜利,这样也就转化为n-1情形下的经典巴什博奕,那么结论也很容易得出:当 ( m + 1 ) ∣ ( n − 1 ) \mathbf{(m+1)|(n-1)} (m+1)∣(n−1)先手必败,否则先手必胜。
扩展二:假设每次可以拿的石子数为[a,b],当石子数小于a的时候不能拿,不能拿石子的一方失败,那么结果如何?
这时候问题变得稍微复杂一些,设
n
=
k
⋅
(
a
+
b
)
+
r
(
0
≤
r
<
a
+
b
)
\mathbf{n=k\cdot (a+b)+r(0\le r<a+b)}
n=k⋅(a+b)+r(0≤r<a+b),然后分如下情况进行讨论:
1.
r
=
0
\mathbf{r=0}
r=0,此时后手的策略很简单,假设每回合先手拿
x
(
a
≤
x
≤
b
)
\mathbf{x(a\le x\le b)}
x(a≤x≤b)颗石子,后手则拿
a
≤
a
+
b
−
x
≤
b
\mathbf{a\le a+b-x\le b}
a≤a+b−x≤b颗石子,这样就能保证后手拿走最后一颗石子,取得胜利。因此这种情况下先手必败。
2.
r
∈
(
0
,
a
)
\mathbf{r\in (0,a)}
r∈(0,a),由于这r个石子最终谁也拿不了,故类似局面1,先手必败。
3.
r
∈
[
a
,
b
]
\mathbf{r\in [a,b]}
r∈[a,b],如果先手拿走r颗石子,那么后手必定就面临局面1,也就是说先手必胜。
4.
r
∈
(
b
,
a
+
b
)
\mathbf{r\in (b,a+b)}
r∈(b,a+b),这时候先手拿走b颗石子,就变成了局面2,也就是说先手必胜。
综上所述,先手必胜当且仅当 r ∈ [ a , a + b ) \mathbf{r\in [a,a+b)} r∈[a,a+b)。
扩展三:在扩展二的基础上,不能拿石子的一方胜利,那么结果如何?
类比于扩展一的思路,将扩展二结论中的n替换为n-a即可。
扩展四:在扩展二的基础上,假设当石子数小于a的时候必须一次性拿完,那么结果如何?
设
n
=
k
⋅
(
a
+
b
)
+
r
(
0
≤
r
<
(
a
+
b
)
)
\mathbf{n=k\cdot (a+b)+r(0\le r<(a+b))}
n=k⋅(a+b)+r(0≤r<(a+b)),这里直接给出结论(证明还没想好):
当且仅当
r
∈
[
1
,
a
)
∪
[
a
,
b
]
\mathbf{r\in [1,a)\cup[a,b]}
r∈[1,a)∪[a,b]时先手必胜。
扩展五:在扩展四的基础上,假设不能拿石子的一方胜利,问结果如何?
同扩展三,将扩展四结论中的n替换为n-a即可。
尼姆博弈及扩展
普通尼姆博弈
问题:有两个绝顶聪明的人在玩取石子游戏,假设有n堆石子,每个人可以轮流选择某一堆然后从中拿走任意数量的石子(不能为0),如果没有石子可取就失败,问先手还是后手胜利。
通过前面的巴什博奕的思考过程我们可以有所启发,首先是利用先手和后手的概念在讨论各个局面的时候显得并不是那么方便,因此我们可以引入必胜局面和必败局面的概念,这对于后续其他博弈游戏的讨论也将大有裨益。
首先明确一点,在必胜局面下先手必胜,在必败局面下先手必败。
必胜局面(N-position):存在一种合法操作使转化为必败局面。
必败局面(P-position):任意一种合法操作都使其转化为必胜局面。
这上面的两个概念很容易理解,可以结合前面的巴什博奕进行思考。
有了这两个概念,我们所有工作的重心就变成了寻找必胜局面和必败局面。而在本题中的必胜局面和必败局面并不是那么容易寻找,我们先提前给出结论:
当且仅当所有堆石子数的异或和为0的时候是必败局面,其他局面都是必胜局面。
要想证明上述结论,我们只需要看它是否满足必胜局面和必败局面的定义即可。
1.当所有堆石子数为0的时候,满足为必败局面且异或和为0。
2.当所有堆石子数异或和不为0的时候,假设异或和为y,则必定存在一堆石子数量为x,对y的最高位的1有贡献,我们将x替换为 x ⊕ y \mathbf{x\oplus y} x⊕y,那么新的异或和变为了 ( x ⊕ y ) ⊕ ( x ⊕ y ) = 0 \mathbf{(x\oplus y)\oplus(x\oplus y)=0} (x⊕y)⊕(x⊕y)=0,再看操作是否合法,由于x与y的最高位一样,因此 x ⊕ y \mathbf{x\oplus y} x⊕y 一定会把最高位抵消掉,也就是说 x ⊕ y < x \mathbf{x\oplus y<x} x⊕y<x,所以说将x变为 x ⊕ y \mathbf{x\oplus y} x⊕y是一种合法操作。综上,当所有堆石子数异或和不为0的时候,存在一种合法操作使得所有堆石子数异或为0,即上文中提到的存在一种合法操作使得必胜局面变为必败局面。
3.当所有堆石子异或为0且存在一堆石子不为0的时候,不管怎么拿石子,一定会导致所有堆石子异或和不为0,因此对于任意合法操作都一定使必败局面转话为必胜局面,也满足条件。
综上所述,“当且仅当所有堆石子数的异或和为0的时候是必败局面,其他局面都是必胜局面。” 的结论成立。
anti-Nim和游戏(反尼姆博弈)
问题:有两个绝顶聪明的人在玩取石子游戏,假设有n堆石子,每个人可以轮流选择某一堆然后从中拿走任意数量的石子(不能为0),取走最后一颗石子的一方失败,问先手还是后手胜利。
反尼姆博弈与尼姆博弈唯一的差别在于输赢的判定反了一下,但结论并不是反一下就可以套过来用的。
一般要得出结论需要不断地从特殊到一般化,找规律和不断地总结,因此我们还是先给出结论再证明结论。
必胜局面只有两种情况:1.所有堆的石子数都为1并且所有堆石子数异或和为0。
2.存在一堆石子数大于1并且所有堆石子数异或和不为0
要想证明结论可以考虑如下四种局面。
1. 当所有堆的石子数都为1的时候。
(1) 若堆数为偶数(此时所有堆石子数异或和为0),后手必定拿完最后一堆石子,因此是必胜局面;
(2) 若堆数为奇数堆,同理可得是必败局面。
2. 当只有一堆石子数大于1的时候(此时所有堆石子数异或和必不为0)。
(1) 如果总共有偶数堆石子,那么先手可以将石子数大于1的堆拿完从而剩下奇数个石子数为1的堆,这样就回到了局面1-(2),这是一个必败局面,因此 2-(1) 是一个必胜局面;
(2) 如果总共有奇数堆石子,那么先手可以将石子数大于1的堆拿到只有一颗石子从而变成就数个石子数为1的堆,这样又回到了局面 1-(2),因此 2-(2) 也是一个必胜局面。
综上所述局面2是一个必胜局面。
3. 当有大于1堆的石子数都大于1且所有堆石子数异或和不为0的时候。类似于普通尼姆博弈的策略,我们设这个异或和为y,然后找到对y的最高位的1具有贡献的堆,设其石子数为x,然后让x变为
x
⊕
y
\mathbf{x\oplus y}
x⊕y,这样就能够将异或和不为0的局面(必胜局面)转化为异或和为0的局面(必败局面)。并且由于同时存在两堆及以上石子数大于1,并且一次性只能操作一堆石子,所以转化为异或和为0的局面的时候也必定存在至少两堆的石子数大于1(一堆石子数大于1的局面必定不可能异或和为0)。因此必胜局面可以转化为必败局面。
4. 当有大于1堆石子都大于1且所有堆石子数异或和为0的时候。类似于普通尼姆博弈,这时候拿任意一堆的任意数量的石子都会导致异或和不为0且至少存在一堆石子数大于1的局面产生,也就是说在必败局面下,无论怎么合法操作都会转化为必胜局面。
综上四种局面,我们就证明了必胜局面可以转化为必败局面,必败局面必定转化为必胜局面。
Nim-k博弈
问题:有两个绝顶聪明的人在玩取石子游戏,假设有n堆石子,每个人可以轮流在不超过k堆石子中拿走任意数量的石子(不能为0),无法拿石子的一方失败,问先手还是后手胜利。
还是延续之前尼姆博弈的基本思路,给出结论,证明结论。
当且仅当所有堆石子数在二进制下的各位上的1的数目都满足是k+1的倍数的时候是必败局面。
1.石子数为0的时候是必败局面且各位上的1的数目均为0,满足为k+1的倍数。
2.当各位上1的数目都是k+1的倍数且存在至少一位上1的数目不为0的时候,由于只能改变k堆的石子数,故同一位上最多增加或减少k个1,故任意合法操作都必将使得至少一位上的1的个数不为k+1的倍数,也就是必败局面必将转向必胜局面。
3.当存在一位上的1的数目不是k+1的倍数的时候,一定存在合法操作使得各位上的1的数目都是k+1的倍数。下面我们将构造出这种合法的操作。
假设我们现在考虑到第i位,而对于更高的位都已经满足1的个数是k+1倍数的条件,并且已经合法更改了m个堆的石子数的值,而在除去这m堆以外的剩余堆里面在第i位上有x个1,令r=x%(k+1)。易知对于这m堆在第i位上可以任意选择1和0的分布,于是分类讨论有两种情况。
(1).如果
r
≤
k
−
m
\mathbf{r\le k-m}
r≤k−m,我们可以将第m堆和r堆中的所有石子数的第i位置为0。
(2).如果
r
>
k
−
m
\mathbf{r>k-m}
r>k−m,我们可以在m堆中选择k+1-r 堆在第i位置为1,而其他堆在第i位置为0,由于
k
+
1
−
r
<
k
+
1
−
(
k
−
m
)
<
1
+
m
⇒
k
+
1
−
r
≤
m
\mathbf{k+1-r<k+1-(k-m)<1+m\Rightarrow k+1-r\le m}
k+1−r<k+1−(k−m)<1+m⇒k+1−r≤m,因此一定能够在m堆中选择k+1-r堆。
由于对于任意i都能找到合法的操作满足条件,故一定存在合法的操作使得必胜局面转化为必败局面。
综上所述,给出的结论是正确的。
Nim-m博弈
问题:有两个绝顶聪明的人在玩取石子游戏,假设有n堆石子,每个人可以轮流在任意一堆石子中中拿走不超过k个石子(不能为0),无法拿石子的一方失败,问先手还是后手胜利。
结论:当且仅当所有堆石子数模k+1的异或和为0的时候为必败局面
证明方法基本同上。
SG函数的引入
前面谈到了三种Nim游戏,事实上这三种游戏都具有一个共性,用专业的术语来说它们都属于经典的公平组合游戏(ICG)。
关于ICG有如下定义(引自百度百科):
满足以下条件的游戏是ICG(可能不太严谨):
1、有两名选手;
2、两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动;
3、对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作、以前的任何操作、骰子的点数或者其它什么因素;
4、如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手负。根据这个定义,很多日常的游戏并非ICG。例如象棋就不满足条件3,因为红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操作。
对于所有的ICG都有一个统一的解决方案,我们先看一个模型:给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移动者判负。
如果我们把Nim游戏中的每一个石堆的石子数看作是一个状态,对应到一个棋子,合法操作(拿石子)看作是移动棋子,合法操作的多种可能的结果对应到有向图的一条边。那么游戏失败的标志就是所有的棋子都被移到一个出度为0的节点。
这样我们就合理化地从Nim游戏抽象出来了一个关于有向无环图的模型(无环是因为局面是不可逆的)。事实上不仅是Nim游戏,所有的ICG都可以抽象为这个模型。在这个模型中,棋子的移动互不关联,仅仅取决于棋子在有向图中的位置,完美的符合了ICG的定义。
为了更好地表示棋子在有向图上的移动,这里将正式给出SG函数的定义:
S
G
(
x
)
=
m
e
x
{
S
G
(
y
)
∣
y
是
x
的后继
}
\mathbf{SG(x)=mex \{ SG(y) | y是x的后继\}}
SG(x)=mex{SG(y)∣y是x的后继}(
m
e
x
{
a
1
,
a
2
.
.
.
a
n
}
代表
{
a
1
,
a
2
.
.
.
a
n
}
中没有出现的最小非负整数,特别地
m
e
x
{
}
=
0
)
mex\{a_1,a_2...a_n\}代表\{a_1,a_2...a_n\}中没有出现的最小非负整数,特别地mex\{\}=0)
mex{a1,a2...an}代表{a1,a2...an}中没有出现的最小非负整数,特别地mex{}=0)
在有向图的每一个节点上定义一个SG值,这样我们就可以通过SG值来表征每个点的状态。下面来思考这些SG值的意义,先考虑图上只有一个棋子的情况,如果棋子位于的点的出度为0,自然地SG值也是0,意味着这是一个必败局面。如果沿着边反向走,从终点出发走到的第一个点对应的SG值必然不为0,并且该点对应的也是一个必胜局面,因为存在一条边走向必败局面。根据这个逻辑,我们可以猜测SG为0的时候对应的局面是必败局面,否则是必胜局面。
证明也非常简单,就像前面证明Nim游戏一样,只要能够证明必胜局面能够走向必败局面,必败局面一定走向必胜局面即可。
证明:1.对于出度为0的点SG为0,且是必败局面,符合定义。
2.对于SG不为0的点,根据SG函数定义可知该点的后继存在一个点的SG为0,故必胜局面可以走向必败局面。
3.对于SG为0且出度不为0的点,根据SG函数的定义可知该点的后继不存在SG为0的点,即所有后继SG均大于0,故必败局面必走向必胜局面
由上面的证明可以知道的是在图只有一个棋子的情况下,通过SG是否为0就能够判定必胜局面和必败局面。对于多个棋子的情况,我们先给出结论:
设有n个棋子,每个棋子对应的SG值为
{
S
G
1
,
S
G
2
,
S
G
3
.
.
.
S
G
n
}
\mathbf{\{SG_1,SG_2,SG_3...SG_n\}}
{SG1,SG2,SG3...SGn},如果
S
G
1
⊕
S
G
2
⊕
S
G
3
⊕
.
.
.
⊕
S
G
n
=
0
\mathbf{SG_1\oplus SG_2 \oplus SG_3 \oplus...\oplus SG_n=0}
SG1⊕SG2⊕SG3⊕...⊕SGn=0则这是一个必败局面,否则是一个必胜局面。
证明也非常简单,参考前面关于尼姆博弈的证明,我们可以类似地给出如下证明。
证明:1.当所有点的出度为0的时候是一个必败局面,且满足
S
G
1
⊕
S
G
2
⊕
S
G
3
⊕
.
.
.
⊕
S
G
n
=
0
\mathbf{SG_1\oplus SG_2 \oplus SG_3 \oplus...\oplus SG_n=0}
SG1⊕SG2⊕SG3⊕...⊕SGn=0,符合定义。
2.当
S
G
1
⊕
S
G
2
⊕
S
G
3
⊕
.
.
.
⊕
S
G
n
=
0
\mathbf{SG_1\oplus SG_2 \oplus SG_3 \oplus...\oplus SG_n= 0}
SG1⊕SG2⊕SG3⊕...⊕SGn=0且存在节点出度不为0的的时候,由于任意走一个棋子都会改变相应地SG值,也将导致SG异或和不为0,故从必败局面出发必将走向必胜局面。
3.当
S
G
1
⊕
S
G
2
⊕
S
G
3
⊕
.
.
.
⊕
S
G
n
≠
0
\mathbf{SG_1\oplus SG_2 \oplus SG_3 \oplus...\oplus SG_n\ne 0}
SG1⊕SG2⊕SG3⊕...⊕SGn=0的时候,一定存在移动方案使得异或和为0。类比尼姆博弈的构造方法,设异或和为y,那么找到对y的最高位的1有贡献的
S
G
i
\mathbf{SG_i}
SGi,然后让该棋子走向SG值为
S
G
i
⊕
y
(
S
G
i
⊕
y
<
S
G
i
)
\mathbf{SG_i\oplus y(SG_i\oplus y<SG_i)}
SGi⊕y(SGi⊕y<SGi)的节点(这个节点一定能走到,参考SG函数的定义),这样就能让所有棋子的SG值异或和为0,也就是说存在一种合法移动使得必胜局面转化为必败局面。
综上三点,我们成功证明了这个结论。
然后进一步地可以发现,由于棋子之间并不存在影响,证明过程也并不要求棋子到底位于哪张有向图上,也就是说可以让棋子位于不同的图上,然后每次移动都可以去选择让哪个棋子移动,这样整个游戏也变得更加灵活。
概括来说,对于任意多个不同规则的ICG,我们都可以将这些ICG的规则转化为若干有向图上的边,将游戏的操作转化为棋子的移动,将游戏的局面看做有向图上的若干个棋子的当前所在位置。然后通过计算每个棋子对应的SG值的异或和来确定当前局面是必胜局面或是必败局面。
计算SG函数的方法可以打表找规律,也可以数学推公式,还可以用结论。
下面先给出一些常见的游戏规则对应的SG函数,以取石子为例(对应有向图中点的标号与石子个数相同,因为点的标号的目的在于区分不同的状态,而石子个数显然能够区分不同的状态)。
1.可选择1~m颗石子,
S
G
[
x
]
=
S
G
[
x
]
%
(
m
+
1
)
\mathbf{SG[x]=SG[x]\%(m+1)}
SG[x]=SG[x]%(m+1)。
2.可选步数为任意步,
S
G
[
x
]
=
x
\mathbf{SG[x]=x}
SG[x]=x。
3.可选步数为规定的整数,用打表模板。
下面给出打表的模板:
#include <bits/stdc++.h>
#define FOR(i,a,b) for(register int i=(a);i<(b);++i)
#define ROF(i,a,b) for(register int i=(a);i>=(b);--i)
#define pi pair<int,int>
#define mk(a,b) make_pair(a,b)
#define mygc(c) (c)=getchar()
#define mypc(c) putchar(c)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 10000;
const int maxm = 100;
const int inf = 2147483647;
typedef long long ll;
const double eps = 1e-9;
const long long INF = 9223372036854775807ll;
ll qpow(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c;b>>=1;}return ans;}
inline void rd(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
inline void rd(ll *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
inline void rd(db *x){scanf("%lf",x);}
inline int rd(char c[]){int i,s=0;for(;;){mygc(i);if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF) break;}c[s++]=i;for(;;){mygc(i);if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF) break;c[s++]=i;}c[s]='\0';return s;}
inline void rd(int a[],int n){FOR(i,0,n)rd(&a[i]);}
inline void rd(ll a[],int n){FOR(i,0,n)rd(&a[i]);}
template <class T, class S> inline void rd(T *x, S *y){rd(x);rd(y);}
template <class T, class S, class U> inline void rd(T *x, S *y, U *z){rd(x);rd(y);rd(z);}
template <class T, class S, class U, class V> inline void rd(T *x, S *y, U *z, V *w){rd(x);rd(y);rd(z);rd(w);}
inline void wr(int x){if(x < 10) putchar('0' + x); else wr(x / 10), wr(x % 10);}
inline void wr(int x, char c){int s=0,m=0;char f[10];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
inline void wr(ll x, char c){int s=0,m=0;char f[20];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
inline void wr(db x, char c){printf("%.15f",x);mypc(c);}
inline void wr(const char c[]){int i;for(i=0;c[i]!='\0';i++)mypc(c[i]);}
inline void wr(const char x[], char c){int i;for(i=0;x[i]!='\0';i++)mypc(x[i]);mypc(c);}
template<class T> inline void wrn(T x){wr(x,'\n');}
template<class T, class S> inline void wrn(T x, S y){wr(x,' ');wr(y,'\n');}
template<class T, class S, class U> inline void wrn(T x, S y, U z){wr(x,' ');wr(y,' ');wr(z,'\n');}
template<class T> inline void wra(T x[], int n){int i;if(!n){mypc('\n');return;}FOR(i,0,n-1)wr(x[i],' ');wr(x[n-1],'\n');}
vector<int>f;
int sg[maxn],vis[maxn];
void getSG(int n,int maxx){//打表sg[0],sg[1]...sg[n],maxx代表sg值的上限
sort(f.begin(),f.end());
memset(sg,0,sizeof(int)*(n+1));
FOR(i,1,n+1){
FOR(j,0,f.size()){
if(f[j]>i)break;
vis[sg[i-f[j]]]=1;
}
FOR(j,0,maxx+1)if(!vis[j]){
sg[i]=j;
break;
}
FOR(j,0,f.size()){
if(f[j]>i)break;
vis[sg[i-f[j]]]=0;
}
}
}
int main(){
//测试
f.push_back(1);
f.push_back(5);
getSG(100,50);
wra(sg,100);
}
尼姆博弈的扩展
通过将ICG抽象为有向图,在此理论基础上研究SG函数的规律,我们可以解决很多的ICG,下面将给出一些经典的题目来熟悉SG函数的运用,这些题目同时也是尼姆博弈的扩展版本。
问题一:有两个绝顶聪明的人在玩取石子游戏,假设有n堆石子,每个人可以轮流选择一堆中拿1~m颗石子,无法拿石子的一方失败,问先手还是后手胜利。
题解:先将问题抽象为有向图模型:每堆石子对应到一个棋子,n堆石子对应n个棋子,由于每个棋子的移动规则相同,所以n个棋子位于同一张有向图上,然后求出每个棋子的SG值即可。
根据前面得到的结论可知,
S
G
[
x
]
=
S
G
[
x
]
%
(
m
+
1
)
\mathbf{SG[x]=SG[x]\%(m+1)}
SG[x]=SG[x]%(m+1),有n堆石子,所以只需要求出n个棋子的SG值的异或和即可,异或和为0则为必败局面,否则为必胜局面。
问题二:有两个绝顶聪明的人在玩取石子游戏,假设有n堆石子放在标号为1~n的台阶上,台阶高度按标号递增,0标号代表地面。现在每个人轮流取石子,每次可以从标号为i(i>0)的台阶上取任意数量(不能为0)的石子放在标号为i-1的台阶上,如果i为1就是放在地面上。如果没有石子可取就失败,问先手胜利还是后手胜利。
题解:这道题是经典的阶梯博弈,需要在传统Nim游戏上进行转换,注意到如果一方从偶数台阶上取石子放到奇数台阶上的时候,另一方可以立刻可以把这些石子放到下一个偶数台阶上,直到放到地面,如果这样操作的话,对于奇数台阶上的石子来说是没有变化的。考虑为何会产生这种操作,假设只考虑奇数台阶上的石子时是先手胜,那么先手只需要操作奇数台阶的石子即可,后手虽然也可以操作奇数台阶上的石子,但是由于奇数台阶是对先手来说是必胜局面,意味着总有一次轮到后手操作的时候后手不得不操作偶数台阶(因为奇数台阶上的石子都没有了),先手为了保证自己在奇数台阶上的优势一定会将后手刚从偶数台阶推向奇数台阶的石子又推向下一个偶数台阶,相当于奇数台阶上的局势没有发生变化,直到偶数台阶石子都消失的时候先手就胜利了。而当奇数台阶上的局面是必败局面的时候同理后手一定会类似地维护奇数台阶上的局面,一旦先手将偶数台阶上的石子推向奇数台阶时后手也一定会将其推向下一个偶数台阶直到地面,最终导致先手的失败。
综上,这道题经过转化后就只需要考虑奇数台阶上的局面即可,将奇数台阶上的石子推向偶数台阶的操作可以视为拿走奇数台阶上的石子,这就与传统的尼姆博弈没有任何区别了,套用SG函数的计算方法即可判定胜负。
威佐夫博弈
问题:有两堆各若干个石子,两个人轮流从某一堆取至少一个或同时从两堆中取同样多的石子,规定每次至少取一个,多者不限,最后取光者得胜,问先手胜还是后手胜。
威佐夫博弈(Wythoff)也是一种ICG,不过它的SG值并不好求解,因此需要从另外的角度思考这种博弈的解决方案。
我们用二元组(a,b)表示两堆石子的数量,且a<=b,然后考虑必败局面的时候a与b的关系。
首先(0,0)是必败局面,接下来一个必败局面是(1,2),其次是(3,5),然后是(4,7),(6,10),(8,13)…设第i个必败局面为
(
a
i
,
b
i
)
\mathbf{(a_i,b_i)}
(ai,bi),i从0开始,根据规律可以猜测
a
i
=
m
e
x
{
a
0
,
b
0
,
a
1
,
b
1
.
.
.
a
i
−
1
,
b
i
−
1
}
,
b
i
=
a
i
+
i
\mathbf{a_i=mex\{a_0,b_0,a_1,b_1...a_{i-1},b_{i-1}\},b_i=a_i+i}
ai=mex{a0,b0,a1,b1...ai−1,bi−1},bi=ai+i。
下面证明这个规律是正确的。
1.(0,0) 是一个必败局面,符合定义。
2.
(
a
i
,
b
i
)
(
a
i
,
b
i
不为
0
)
\mathbf{(a_i,b_i)(a_i,b_i不为0)}
(ai,bi)(ai,bi不为0)局面可以有三种转化方式,一是让
a
i
\mathbf{a_i}
ai减少,二是让
b
i
\mathbf{b_i}
bi减少,三是让
a
i
\mathbf{a_i}
ai与
b
i
\mathbf{b_i}
bi同时减少一个相同的值k(k>0)。
前两种转化方式的结果是类似地,以第一种为例,由于
a
i
=
m
e
x
{
a
0
,
b
0
,
a
1
,
b
1
.
.
.
a
i
−
1
,
b
i
−
1
}
\mathbf{a_i=mex\{a_0,b_0,a_1,b_1...a_{i-1},b_{i-1}\}}
ai=mex{a0,b0,a1,b1...ai−1,bi−1},所以
a
i
\mathbf{a_i}
ai与前面所有的对偶的a与b的值都不相同,由于
b
i
=
a
i
+
i
>
b
i
−
1
=
a
i
−
1
+
i
−
1
\mathbf{b_i=a_i+i>b_{i-1}=a_{i-1}+i-1}
bi=ai+i>bi−1=ai−1+i−1,故
b
i
\mathbf{b_i}
bi也一定与前面的所有对偶的a与b的值不相同,因此当
a
i
\mathbf{a_i}
ai减少后得到的偶对也一定不可能与之前的偶对相同(之后的更不可能)。假设这个新的局面是
(
a
i
′
,
b
i
)
\mathbf{(a_i',b_i)}
(ai′,bi),故
(
a
i
′
,
b
i
)
\mathbf{(a_i',b_i)}
(ai′,bi)不是一个必败局面,也就是说它是一个必胜局面,也就是说通过前两种转化方式一定将必败局面转化为必胜局面。
对于第三种转化方式,由于
a
i
\mathbf{a_i}
ai与
b
i
\mathbf{b_i}
bi同时减少了一个值k,设这个新得到的局面为
(
a
i
′
,
b
i
′
)
\mathbf{(a_i',b_i')}
(ai′,bi′),这意味着它们的差值并不会变,仍然是i,而对于任意偶对
(
a
j
,
b
j
)
(
j
≠
i
)
\mathbf{(a_j,b_j)}(j\ne i)
(aj,bj)(j=i)而言,它们的差值为
j
≠
i
\mathbf{j\ne i}
j=i,因此不存在偶对与
(
a
i
′
,
b
i
′
)
\mathbf{(a_i',b_i')}
(ai′,bi′)相同,也就意味着
(
a
i
′
,
b
i
′
)
\mathbf{(a_i',b_i')}
(ai′,bi′)并不是一个必败局面,即是一个必胜局面。这样再第三种转化下必败局面也会转化为必胜局面。
综上三种转化方式均会导致必败局面转化为必胜局面。
3.对于一个必胜局面
(
x
,
y
)
(
x
≤
y
)
\mathbf{(x,y)(x\le y)}
(x,y)(x≤y)而言,满足它不是任意一个
(
a
i
,
b
i
)
\mathbf{(a_i,b_i)}
(ai,bi)对,首先
a
i
与
b
i
\mathbf{a_i与b_i}
ai与bi足够取到所有的非负整数(看这个偶对的定义即可理解),故x的值可以分为两种情况。
当
x
=
a
i
\mathbf{x=a_i}
x=ai时,若
y
>
b
i
\mathbf{y>b_i}
y>bi,那么从y的那堆取走
y
−
b
i
\mathbf{y-b_i}
y−bi个石子即可;若
y
<
b
i
\mathbf{y<b_i}
y<bi,假设
j
=
y
−
x
\mathbf{j=y-x}
j=y−x,只需要让x与y同时减去
a
i
−
a
j
\mathbf{a_i-a_j}
ai−aj即可(注意到
a
j
<
a
i
\mathbf{a_j<a_i}
aj<ai一定成立)。
当
x
=
b
i
\mathbf{x=b_i}
x=bi时,则
y
≥
x
≥
a
i
\mathbf{y\ge x\ge a_i}
y≥x≥ai,因此只需要让y减去
y
−
a
i
\mathbf{y-a_i}
y−ai即可,转化为
(
b
i
,
a
i
)
\mathbf{(b_i,a_i)}
(bi,ai)的偶对。
综上在所有情况下必胜局面都有一种合法操作转化为必败局面。
到此我们已经证明了必败局面当且仅当 ( a i , b i ) \mathbf{(a_i,b_i)} (ai,bi),其中 a i = m e x { a 0 , b 0 , a 1 , b 1 . . . a i − 1 , b i − 1 } , b i = a i + i \mathbf{a_i=mex\{a_0,b_0,a_1,b_1...a_{i-1},b_{i-1}\},b_i=a_i+i} ai=mex{a0,b0,a1,b1...ai−1,bi−1},bi=ai+i。
不过这还不够,如果要像这样递推下去的话复杂度显然太高了,数字一大就很难给出正解。因此解决本题还需要找到关于
a
i
\mathbf{a_i}
ai和
b
i
\mathbf{b_i}
bi的确切公式。解决这个问题需要用到一个引理:Beatty 定理(贝蒂定理)
定理描述如下:设集合
P
=
{
p
∣
p
=
⌊
n
x
⌋
,
n
∈
N
+
}
,
Q
=
{
q
∣
q
=
⌊
m
y
⌋
,
m
∈
N
+
}
\mathbf{P=\{p|p=\lfloor nx\rfloor,n\in N^+ \},Q=\{q|q=\lfloor my\rfloor,m \in N^+\}}
P={p∣p=⌊nx⌋,n∈N+},Q={q∣q=⌊my⌋,m∈N+},对于两个无理数x,y,若其满足
1
x
+
1
y
=
1
\mathbf{\frac 1x+\frac 1y=1}
x1+y1=1,则
P
∩
Q
=
∅
且
P
∪
Q
=
N
+
\mathbf{P\cap Q=\empty且P\cup Q=N^+}
P∩Q=∅且P∪Q=N+。
有了贝蒂定理之后就可以得到:
a
i
=
⌊
i
⋅
5
+
1
2
⌋
,
b
i
=
⌊
i
⋅
5
+
3
2
⌋
\mathbf{a_i=\lfloor i\cdot \frac{\sqrt 5+1}{2}\rfloor,b_i=\lfloor i\cdot \frac{\sqrt 5+3}{2}\rfloor}
ai=⌊i⋅25+1⌋,bi=⌊i⋅25+3⌋
容易验证
a
i
\mathbf{a_i}
ai和
b
i
\mathbf{b_i}
bi能够取遍所有非负整数,且满足
b
i
−
a
i
=
i
\mathbf{b_i-a_i=i}
bi−ai=i。
综上所述,对于 (x,y)(x<=y) 局面,只需要验证一下
x
=
⌊
(
y
−
x
)
⋅
5
+
1
2
⌋
\mathbf{x=\lfloor (y-x)\cdot \frac{\sqrt 5+1}{2}\rfloor}
x=⌊(y−x)⋅25+1⌋这个等式是否成立即可,成立的话就是必败局面,否则为必胜局面。
斐波拉契博弈
问题:有一堆个数为n(n>=2)的石子,有两个绝顶聪明的人轮流取石子,先手第一次取石子的时候不能取完,此后每个人取的石子数量都不能超过对方最近一次取石子数量的两倍,取完最后一颗石子的人胜利,问先手胜还是以后手胜。
这道题并不是一道ICG,因为双方的决策并不只受当前局面的影响,还受到对方决策的影响,因此这道题的解决办法还是得另辟蹊径。
先给出结论:当且仅当n为斐波拉契数列中的项的时候为必败局面。
设斐波拉契数列的第i项为
f
i
\mathbf{f_i}
fi考虑用数学归纳法证明这个结论。
当n=2的时候,显然是必败局面。
假设当
n
=
f
i
(
i
<
=
k
)
\mathbf{n= f_i (i<=k)}
n=fi(i<=k)的时候是必败局面,下面证明
n
=
f
i
+
1
\mathbf{n=f_{i+1}}
n=fi+1的时候也是必败局面(注意到这不是ICG,因此不能套用前面胜利局面与失败局面的定义来证明本题)。此时满足
f
i
+
1
=
f
i
+
f
i
−
1
\mathbf{f_{i+1}=f_i+f_{i-1}}
fi+1=fi+fi−1,由于
f
i
<
=
2
⋅
f
i
−
1
\mathbf{f_i<=2\cdot f_{i-1}}
fi<=2⋅fi−1,先手必定不能拿多于或等于
f
i
−
1
\mathbf{f_{i-1}}
fi−1个石子,此外,由于
n
=
f
i
−
1
\mathbf{n=f_{i-1}}
n=fi−1是必败局面,故后手一定可以刚好拿走
f
i
−
1
\mathbf{f_{i-1}}
fi−1中的最后一颗石子。由于后手最多可以拿先手所拿石子的两倍,故后手最多恰好拿走
2
3
f
i
−
1
\mathbf{\frac 23f_{i-1}}
32fi−1从而使得总石子数变为
f
i
\mathbf{f_{i}}
fi,此时先手最多可以拿
4
3
f
i
−
1
\mathbf{\frac 43f_{i-1}}
34fi−1个石子,不过
4
3
f
i
−
1
−
f
i
=
1
3
f
i
−
1
−
f
i
−
2
<
0
\mathbf{\frac 43f_{i-1}-f_{i}=\frac 13f_{i-1}-f_{i-2}<0}
34fi−1−fi=31fi−1−fi−2<0故先手仍不可能拿完最后这
f
i
\mathbf{f_i}
fi个石子,如果先手不能拿完的话,考虑到当初始局面
n
=
f
i
\mathbf{n=f_i}
n=fi的时候先手必败,且是在先手任意拿石子(不能拿完)的前提下必败,此时则局限于
[
1
,
4
3
f
i
−
1
]
\mathbf{[1,\frac 43f_{i-1}]}
[1,34fi−1]的范围,则必败无疑,故无论如何抉择在
n
=
f
i
+
1
\mathbf{n=f_{i+1}}
n=fi+1的局面下先手都会失败。
综上所述,当n为斐波拉契的项时一定是必败局面。
现在再考虑n不为斐波拉契的项时的局面。这时候需要用到Zeckendorf定理(齐肯多夫定理):任何正整数都可以表示为若干个不连续的斐波拉契数之和。
先说明如何将正整数拆分为斐波拉契数,先找到一个斐波拉契数
f
i
k
\mathbf{f_{i_k}}
fik使得
f
i
k
<
n
<
f
i
k
+
1
\mathbf{f_{i_k}<n<f_{i_k+1}}
fik<n<fik+1,然后让n减去
f
k
\mathbf{f_k}
fk得到
n
′
=
n
−
f
i
k
\mathbf{n'=n-f_{i_k}}
n′=n−fik,再对
n
′
\mathbf{n'}
n′重复这个过程找到下一个斐波拉契数
f
i
k
−
1
\mathbf{f_{i_{k-1}}}
fik−1使得
f
i
k
−
1
≤
n
′
<
f
i
k
−
1
+
1
\mathbf{f_{i_{k-1}} \le n' < f_{i_{k-1}+1}}
fik−1≤n′<fik−1+1,然后让
n
′
\mathbf{n'}
n′减去
f
i
k
−
1
\mathbf{f_{i_{k-1}}}
fik−1得到
n
′
′
\mathbf{n''}
n′′…以此类推我们就能得到
n
=
f
i
1
+
f
i
2
+
.
.
.
+
f
i
k
(
i
1
<
i
2
<
.
.
.
<
i
k
且不存在连续的段
)
(
k
>
=
2
)
\mathbf{n=f_{i_1}+f_{i_2}+...+f_{i_k}(i_1<i_2<...<i_k 且不存在连续的段)(k>=2)}
n=fi1+fi2+...+fik(i1<i2<...<ik且不存在连续的段)(k>=2)
考虑构造一种合法的操作使得先手胜利。先手第一步拿走
f
i
1
\mathbf{f_{i_1}}
fi1个石子,由于
2
⋅
f
i
1
<
f
i
2
\mathbf{2\cdot f_{i_1}<f_{i_2}}
2⋅fi1<fi2,故后手不能将
f
i
2
\mathbf{f_{i_2}}
fi2拿完,于是利用前面的结论我们可以知道先手必定可以拿完
f
i
2
\mathbf{f_{i_2}}
fi2的最后一颗石子,又由于
2
⋅
f
i
2
<
f
i
3
\mathbf{2\cdot f_{i_2}<f_{i_3}}
2⋅fi2<fi3,后手仍然不可能一次性将
f
i
3
\mathbf{f_{i_3}}
fi3拿完…以此类推,每次先手都能拿走
f
j
\mathbf{f_j}
fj的最后一颗石子,最终拿完
f
k
\mathbf{f_k}
fk的最后一颗石子取得胜利。
通过这种构造方法我们发现先手一定会胜利,因此n不为斐波拉契数的时候是必胜局面。
双人零和博弈
双人零和博弈中要求在任意局势下双方受益和为零。假设一方收益矩阵为 A A A,则满足另一方收益矩阵为 − A -A −A。现在考虑一方做出 i i i选择的概率为 p i p_i pi,那么要求 ∑ i p i A i , j ≥ v \sum_ip_iA_{i,j}\ge v ∑ipiAi,j≥v对于 j = 1 , j = 2 , . . . , j = n j=1,j=2,...,j=n j=1,j=2,...,j=n都满足。使得 v v v最大化。考虑令 x i = p i v x_i=\frac{p_i}{v} xi=vpi,满足 ∑ i x i = 1 v \sum_ix_i=\frac 1v ∑ixi=v1,我们的目标是最小化 ∑ i x i \sum_i x_i ∑ixi,同时要满足 n n n个约束即可。这可以用线性规划求解。
其他博弈
take & break模型
问题:给定n堆石子,双方轮流每次可以选择i,j,k三堆石子(i<j<=k),满足第i堆石子至少有一颗,然后从第i堆石子中拿走一颗石子,然后在第j,k堆石子中各加一颗石子(如果j=k那么就加2颗石子),问先手必胜必败?
首先可以发现每个石子是独立的,你可以认为每个石子都是一个单独的ICG游戏,它的sg值只取决于它的位置,因此定义sg函数为 S G ( i ) SG(i) SG(i)其中 i i i代表位置 i i i,显然 i i i位置的一颗石子对应的后继是 j , k j,k j,k处的两颗石子,所以 S G ( x ) = m e x i < j < = k < = n { S G ( j ) x o r S G ( k ) } SG(x)=mex_{i<j<=k<=n}\{SG(j)\;xor\;SG(k)\} SG(x)=mexi<j<=k<=n{SG(j)xorSG(k)},整个游戏的 S G SG SG值是所有石子的 S G SG SG值的异或和。
翻转硬币博弈
问题:给定n个硬币从左到右放一排,有的硬币正面朝上,有的反面朝上,两个人轮流操作,每次操作可以选择一个正面朝上的硬币翻转,同时还可以选择一个该硬币左边的硬币翻转(也可以不选择),不能操作的人失败,问谁必胜。
结论是这个游戏和nim游戏的 S G SG SG函数是一样的,第 i i i个硬币看成石子数为 i i i的一堆石子,整个游戏的 S G SG SG值就是所有石子的 S G SG SG值的异或和。
考虑如何证明。如果只有 1 1 1个硬币正面朝上,我们可以把这个硬币直接变成反面朝上,也可以把它反转后让它左边的某个硬币反面朝上,相当于把这枚硬币向左移动一段位置,容易联想到这个状态变化与nim游戏中一堆石子的数量变化是一致的,即对于位置 i i i的硬币,其 S G ( i ) = i SG(i)=i SG(i)=i。如果有多个硬币正面朝上的话,我们考虑整个游戏的 S G SG SG值,有两种求解方式,第一种是考虑把游戏拆分成多个子游戏,分别求出每个子游戏的 S G SG SG值后再全部异或起来;第二种是直接暴力枚举游戏的所有状态及其后继,通过 S G SG SG函数定义来递推求出每个状态的 S G SG SG值。我们尝试着把翻转硬币这个游戏和nim游戏在第二种方式上建立联系,首先我们随便选择一个编号为 i i i的硬币,这个操作我们映射为选择了石子数为 i i i的那堆石子(注意一开始每堆石子数量都不同),如果我们选择直接翻转这枚硬币,那么相当于直接把这堆石子都拿掉;如果我们选择左边一枚编号为 j j j的反面朝上的硬币反转,相当于让 i i i号硬币向左移动一段位置,等价于让这堆石子数量从 i i i变成 j j j。现在我们发现在这两种状态变化下,翻转硬币游戏和nim游戏的状态变化是一一对应的,那在让我们考虑最后一种状态变化:选择 i i i左边一枚编号为 k k k的正面朝上的硬币反转。第三种变化等价于把这堆石子数量变成 k k k,也就是和另一堆石子数也为 k k k的石子堆相同,注意到这两堆石子的 S G SG SG异或和为0,对整个游戏的 S G SG SG值没有贡献,也就是说这个状态等价于两堆石子都不存在的状态,反映到翻转硬币这个游戏中就等价于 i i i和 k k k号硬币都处于反面向上的状态,所到此为止我们成功建立了这两个游戏的状态转化关系,这些状态转化对 S G SG SG的影响是一模一样的,因此我们可以直接把翻转硬币等价于nim游戏,套用nim游戏的 S G SG SG公式计算即可。
阶梯博弈变式
(POI2003/2004 stage I Game)问题:给定长度为n的一行格子,某些格子上放着硬币,有些是空的,你每次选择一个硬币,放到离它最近的右边的空的格子上,如果右边没有空的格子就直接扔掉。两方轮流操作,不能操作就失败,问谁胜。
这道题如果去研究状态会觉得很复杂,根本无从下手,但是如果把两个空格子之间的硬币都看成放在一个阶梯上,这样你会发现其实这就是一道阶梯博弈!
图上删边博弈
(IPSC 2003 Got Root?)问题:给定一张无向连通图和节点u,每次操作选择一条边删除,然后将那些与节点u不连通的边和点删除。两个玩家轮流操作,不能操作的玩家输掉,问谁获胜。
这道题的解法来自IPSC 2003 Solution to Problem G – Got Root?,以下文字是对该英文题解的归纳总结。更具体的证明见论文《Winning Ways for Your Mathematical Plays》第一卷第7章
首先给出做法:对于一颗树而言,我们可以递归求解这颗树的 S G SG SG函数,如果这颗树根节点是 u u u,那么 S G ( u ) = x o r e d g e ( u , v ) { S G ( v ) + 1 } SG(u)=xor_{edge(u,v)}\{SG(v)+1\} SG(u)=xoredge(u,v){SG(v)+1}。如果是无向图的话,可以证明任何环上的点都可以缩成一个点加环的边数量的自环,这个自环还等价于从该缩点延伸出去的一条额外的边,这样我们可以将所有的边双连通分量都缩成一个点,把所有的自环等价变换为从缩点延伸出去的边,得到的是一颗树,然后按照树的 S G SG SG求解方法来做即可。
证明分为两个步骤。第一步先证明树上的 S G SG SG函数的求解方法的正确性,对于根节点 u u u而言,考虑其一个儿子 v v v及以它为根的子树,我们可以把 v v v和以它为根的子树等价转化为一条长度为 S G ( v ) SG(v) SG(v)的链,在这种转化下我们可以证明 S G ( u ) SG(u) SG(u)不会发生改变。考虑原图对应的游戏是 G G G,在做出这种等价转化后的游戏是 G ′ G' G′,现在考虑 G + G ′ G+G' G+G′这样一个游戏,如果先手必败,那么我们就可以得出 S G ( G ) = S G ( G ′ ) SG(G)=SG(G') SG(G)=SG(G′),方便起见我们只考虑 u u u只有一个儿子 v v v(这样考虑是没问题的,因为 u u u的儿子是相互独立的),在图 G ′ G' G′相应地有 u ′ u' u′和 v ′ v' v′,不过 v ′ v' v′的子树是一条长度为 S G ( v ) SG(v) SG(v)的链。先手一定不能选择 ( u , v ) (u,v) (u,v)或 ( u ′ , v ′ ) (u',v') (u′,v′),一旦选择其中一条边,那么后手就会断开另一条边,这样先手就输了。那么先手就会在 v ′ v' v′为根的子树和 v v v为根的子树上博弈,注意这是两个 S G SG SG相同的子游戏,意味着这两个子游戏的 S G SG SG值为0,因此先手不会拿掉 v v v为根的子树和 v ′ v' v′为根的子树中最后一条边,一旦 v v v为根的子树和 v ′ v' v′为根的子树被清空,那么先手必定要去选择删 ( u , v ) (u,v) (u,v)或 ( u ′ , v ′ ) (u',v') (u′,v′)边,意味着先手还是会输掉博弈,因此证得 S G ( G ) = S G ( G ′ ) SG(G)=SG(G') SG(G)=SG(G′)。于是我们可以把 v v v为根的子树直接等价转化为长度为 S G ( v ) SG(v) SG(v)的一条链,现在 v v v和 u u u多了一条连边,链条长度变成了 S G ( v ) + 1 SG(v)+1 SG(v)+1,一条链的异或函数就是它的长度本身,这就说明了 S G ( u ) = x o r e d g e ( u , v ) { S G ( v ) + 1 } SG(u)=xor_{edge(u,v)}\{SG(v)+1\} SG(u)=xoredge(u,v){SG(v)+1}。
第二步是最艰难的部分,我们需要证明无向图上的任何一个环都可以缩成一个点,环上的所有边对应缩成该缩点上的相同数量的自环。注意自环其实等价于从点连出去的一条额外边。
考虑边数最少,在边数同样少的情况下点数最少的这样一个反例
G
G
G,也就是说在这个反例中,如果把环缩成一个点会导致
S
G
SG
SG值发生改变。那么这样一个反例具有如下特征:
- 把根节点u删除后,剩下的部分仍然连通。
证明:如果不连通就不满足最小原则,我们找到有环的那个连通块,它显然是个更小的反例。 - 任意两个点之间不能有多于三条互不相交的通路。
证明:假设有两个点 x , y x,y x,y存在三条互不相交的通路,那么把 x , y x,y x,y及其三条通路缩成一个点 z z z得到图 G ′ G' G′,我们还是在 G + G ′ G+G' G+G′这个游戏上博弈,由于是反例,那么 S G ( G ) ≠ S G ( G ′ ) SG(G)\ne SG(G') SG(G)=SG(G′),这意味着先手必胜,假设先手选择了必胜策略,即 G G G或 G ′ G' G′中的某条边删除,那么因为后手必输,无论选择哪条边删除先手仍然是必胜,不妨让后手选择跟先手不同图的对称的那条边删除,在后手操作完毕后,我们发现 G G G和 G ′ G' G′都减少了一条边,而目前还是先手必胜。注意到 G G G只减少了一条边,所以能保证 x , y x,y x,y之间至少还有两条互不相交的通路,也就是说这两个点仍然形成了一个环,由于图 G G G已经变得更小了(因为删除了一条边),所以它不是一个反例,所以其中的环再缩点后仍满足 S G SG SG不变,因此现在我们考虑把删除了一条边后的图 G G G做缩点操作,得到的图将和后手删除了一条边后的图 G ′ G' G′一模一样,因此两者 S G SG SG值也一样,这样我们可以得出与前面相反的结论,即先手必败,这是矛盾的,因此任意两点间不存在三条互不相交的通路。 - 任意一个环都必定包含根节点
u
u
u。
证明:利用结论 1 、 2 1、2 1、2我们容易证明该结论,考虑一个环不包含 u u u节点,由于这个环和 u u u节点是连通的,那么有两种情况:- 存在一个节点 v v v是环上的所有节点到节点 u u u的必经节点。在这种情况下显然不满足小性,因为这个环本身就可以作为一个更小的反例。
- 存在多个节点是环上所有节点到 u u u可以经过的节点。在这种情况下,我们任意取这些节点中的两个,假设是 x , y x,y x,y,那么 x x x到 y y y显然存在至少三条通路,这不符合结论 2 2 2。
- 经过
u
u
u节点的环只有一个。
证明:假设有多个环经过 u u u节点,那么任意取两个环,根据结论 3 3 3由于这两个环至少存在一个交点 u u u,因此这两个环上必定能找到两个点 x , y x,y x,y满足这两个点存在至少三条不相交路径,违背了 2 2 2结论,因此只有一个环经过 u u u节点。 -
u
u
u节点上在唯一的环上并且
u
u
u节点的度数为2。
证明:如果 u u u节点又多个分岔,那么多余的分岔只能是树,这些多余的树显然可以删去,因为不满足最小的反例的性质。
这样我们对于这个反例的图像有了清晰的认识,大致如下图所示:
注意那些长长的枝条,它们利用了等价转化,把树转化为一个链条。
现在图
G
G
G已经是最简的形式了,我们考虑图
G
′
G'
G′为图
G
G
G缩点后的情形,除了上图的链条链接到
u
′
u'
u′点外,环上的边都变成连接
u
′
u'
u′的边长为1的边。现在我们考虑在
G
+
G
′
G+G'
G+G′上博弈,我们只要证明先手必败,就表明最小的反例不存在,整个证明也得已结束。
先手可以选择链条中的一条边删除,如果这样的话,后手也选择对称的图中的对应的链条的边删除,这样由于图
G
G
G少了一条边,不是最小的反例了,所以可以做等价转换,图
G
G
G和图
G
′
G'
G′的
S
G
SG
SG值也就保证相等了,这样就是必败了,所以先手一定不能选择链条中的一条边删除。
再考虑先手选择图
G
G
G中环上的一条边删除,如果这样的话,图
G
G
G就变成了一棵树,
G
′
G'
G′也是一颗树,我们面对的游戏是一颗森林!于是考虑套用
S
G
SG
SG计算公式,不过我们把异或改成加法,并且只考虑最后一位的变化,可以发现异或奇偶性与加法奇偶性相同,意味着边数的奇偶性代表了
S
G
SG
SG值的奇数偶性,显然先手只删除了一条边,图
G
+
G
′
G+G'
G+G′中应该只存在奇数条边,因此
S
G
SG
SG为奇数,大于0,意味着此时处于必胜态,也就是说先手必败,因此先手一开始也不能删除图
G
G
G中的环上的一条边。
现在还有最后一种情况,先手可以选择图
G
′
G'
G′中的一条额外边删除,此时我们分三种情况考察一下后手是否必胜:
- 如果图
G
G
G中的环长度为偶数,后手必胜。
证明:考虑初始 G + G ′ G+G' G+G′的情况,此时先手还没有删除 G ′ G' G′中的额外边,我们直接考察 G + G ′ G+G' G+G′的胜败态,由于 G ′ G' G′中有偶数个额外边,我们把这些边删除得到 G ′ ′ G'' G′′,可以肯定 S G ( G ′ ′ ) = S G ( G ′ ) = S G ( G ) SG(G'')=SG(G')=SG(G) SG(G′′)=SG(G′)=SG(G),所以考察 G + G ′ G+G' G+G′的胜败态等价于考察 G + G ′ ′ G+G'' G+G′′的胜败态,在 G + G ′ ′ G+G'' G+G′′中,如果先手删除链条上的一条边,后手就会删除对应链条上的一条边,这样 G G G就可以缩点,导致 G G G和 G ′ ′ G'' G′′相同( G G G会多一些偶数的额外边,但不影响 S G SG SG值),于是 G + G ′ ′ G+G'' G+G′′在删除两条边后变成了必败态;如果一开始先手选择删除 G G G中的偶环上的一条边,那么又会导致 S G SG SG值是个奇数(参照之前的说明),那么显然还是先手必败,因此可以知道 G + G ′ ′ G+G'' G+G′′先手必败,这就证明了 G + G ′ G+G' G+G′先手必败。 - 如果图
G
G
G中存在奇数长度的链条,后手必胜。
证明:先手在删除 G ′ G' G′中的一个额外边后,后手可以选择 G G G中的一条奇数长度的链条,让它长度减1。在做完上述操作后, G G G满足不是最小反例的条件,因此可以把 G G G的环转化为额外边,此时我们发现 G G G的额外边比 G ′ G' G′少一条,因此 G + G ′ G+G' G+G′中额外边的 S G SG SG值异或和为1。然后 G G G中的链条只有一条与 G ′ G' G′中的枝条长度不同,也就是后手选择的那条奇数长度的链条,根据 2 x x o r ( 2 x + 1 ) = 1 2x\;xor\;(2x+1)=1 2xxor(2x+1)=1,我们可以知道 G + G ′ G+G' G+G′中里链条的 S G SG SG值的异或和也为1,因此 G + G ′ G+G' G+G′的 S G SG SG值为链条的 S G SG SG值异或额外边的 S G SG SG值,也就是0,这就说明此时 G + G ′ G+G' G+G′处于必败态,因此先手必败。 - 图
G
G
G链条长度为奇数,枝条全部长度为偶数,后手必胜。
证明:这是最后一种情况,首先我们稍微改一下 G ′ G' G′,让它本身只有一条额外边,显然它的 S G SG SG值不会发生改变,先手删除唯一的那条额外边后, G ′ G' G′中将没有额外边。然后注意到环上每两个相邻边的临接节点都会延伸出去一条链条(除了 u u u根节点),那么有些链条长度可能为0。我们把环切成一条链,起点是 u u u终点也是 u u u, u u u到 u u u之间的边按顺序从 1 1 1开始编号,后手为了胜利,只需从奇数编号的环上的边上做选择(断偶数编号的边会让先手变成必胜,这个性质对目前的证明不重要,我们现在强制后手选择奇数编号的边),如果后手选择了一个奇数编号的边断开,那么环链被分成两半,左半边有偶数条链条,右半边也有偶数条链条,可以发现两边的偶数条链条可以按顺序两两合并成一条链条,长度为和并它的两条链条长度的异或值的二分之一,同时对 G ′ G' G′图我们把所有链条也两两按同样方式合并,额外边的话变为和 G G G中,在这样操作后不会改变整个 G + G ′ G+G' G+G′的 S G SG SG值是否大于0的性质,即原图 S G SG SG大于0,按上述方式合并后 S G SG SG值仍然大于0,如果原图等于0,按上述方式合并后 S G SG SG仍然等于0。为什么可以合并,我们不妨考虑环链的右半边,取最靠左的两根链条,假设长度分别是 a , b a,b a,b, a , b a,b a,b均为偶数,根据树的 S G SG SG值计算公式,这两个链条对应的子树的 S G SG SG值是 ( a + 1 ) x o r b (a+1)xor\;b (a+1)xorb,这个子树往上还连着一条边,如果加上这条边, S G SG SG值是 ( ( a + 1 ) x o r b ) + 1 ((a+1)xor\;b)+1 ((a+1)xorb)+1,注意 a , b a,b a,b是偶数,因此有 ( ( a + 1 ) x o r b ) + 1 = ( a x o r b ) + 2 ((a+1)xor\;b)+1=(a\;xor\;b)+2 ((a+1)xorb)+1=(axorb)+2,如果继续考虑求出整个右半边的 S G SG SG值,我们可以得到这种 S G SG SG值的形式: ( ( ( ( a x o r b ) + 2 ) x o r a ′ x o r b ′ ) + 2 ) x o r a ′ ′ x o r b ′ ′ ) + 2... ((((a\;xor\;b)+2)\;xor\;a'\;xor\;b')+2)\;xor\;a''\;xor\;b'')+2... ((((axorb)+2)xora′xorb′)+2)xora′′xorb′′)+2...,最终结果一定是偶数,所以除个2一定不改变 S G SG SG值是否大于0这个特性,对于相邻链条合并的操作就等价于对 S G SG SG除以2,同理对于 G ′ G' G′而言,我们对它的两两链条合并(按照与 G G G相同的组合),相当于 S G ( G ′ ) / = 2 SG(G')/=2 SG(G′)/=2,这样 G + G ′ G+G' G+G′的 S G SG SG值相当于除以2,由于 S G SG SG值本来就是偶数,除以2不影响它是否大于0的性质。考虑后手断开环链上的任意一个奇数边之后都要做出上述合并操作,我们不妨在后手断开环之前就先把链条两两合并了,假设链条数目有 k k k个,那么在合并后,链条数目有 k 2 \frac k2 2k个,环的长度也要减少 k 2 \frac k2 2k,假设此时得到的新图 G G G成为 n e x t 1 ( G ) next^1(G) next1(G), G ′ G' G′也提前合并,得到的新图记作 n e x t 1 ( G ′ ) next^1(G') next1(G′),那么 [ S G ( G + G ′ ) > 0 ] = [ S G ( n e x t 1 ( G ) + n e x t 1 ( G ′ ) ) > 0 ] [SG(G+G')>0]=[SG(next^1(G)+next^1(G'))>0] [SG(G+G′)>0]=[SG(next1(G)+next1(G′))>0]等式成立,注意如果在 n e x t 1 ( G ) next^1(G) next1(G)奇数长度的环并且所有链条仍然为偶数,那么我们可以继续得到 n e x t 2 ( G ) = n e x t 1 ( n e x t 1 ( G ) ) next^2(G)=next^1(next^1(G)) next2(G)=next1(next1(G)),那么一定存在一个 x x x使得 n e x t x ( G ) next^x(G) nextx(G)中要么存在偶数长度的环,或者存在奇数长度的链条,这时候 n e x t x ( G ) + n e x t x ( G ′ ) next^x(G)+next^x(G') nextx(G)+nextx(G′)的 S G SG SG值一定大于0,故 S G ( G + G ′ ) > 0 SG(G+G')>0 SG(G+G′)>0,所以后手必胜,也就是先手必败。
至此我们证明了环上的点一定可以被缩成一个点加一些自环(或额外的边长为1的边)。
总结
博弈论的知识点不是特别多,但是有些套路不去理解在赛场上就做不出来,因此本文主要是梳理一下关于博弈的基础知识,一遍作者日后复习,也给广大对博弈论感到困惑的读者提供帮助。没有给出练习题,以后有空的话可能还会完善本篇博文。
参考资料及博客:
[1].https://blog.csdn.net/clover_hxy/article/details/53818624
[2].https://www.cnblogs.com/lfri/p/10662291.html
[3].https://www.cnblogs.com/nanjoqin/p/10211576.html
[4].https://www.luogu.com.cn/problem/solution/P2197
[5].https://baike.baidu.com/item/Nim%E6%B8%B8%E6%88%8F/6737105?fr=aladdin
[6].https://baike.baidu.com/item/SG%E5%87%BD%E6%95%B0/1004609?fr=aladdin
[7].https://www.luogu.com.cn/problem/solution/P2252
[8].https://baike.baidu.com/item/%E8%B4%9D%E8%92%82%E5%AE%9A%E7%90%86/2677437?fr=aladdin
[9].https://blog.csdn.net/dgq8211/article/details/7602807
[10].https://baike.baidu.com/item/%E9%BD%90%E8%82%AF%E5%A4%9A%E5%A4%AB%E5%AE%9A%E7%90%86/7612155?fr=aladdin
[11].https://blog.csdn.net/tinyDolphin/article/details/75500903?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param