正在施工中博弈论小结
bash博弈 nim游戏 sg函数 [阶梯nim](https://www.cnblogs.com/RogerDTZ/p/9439540.html) 威佐夫博弈 [斐波那契博弈](https://www.cnblogs.com/Ritchie/p/5762320.html) **打表找规律**[HDU1517](https://vjudge.net/problem/HDU-1517) 对偶博弈 海盗分金(为什么后来金币数不确定?)
👆这些以上都没有
nim k
问题形式:有若干博弈游戏,每次可以一下子进行最多k个游戏,谁无法进行谁输。
结论:整个游戏的SG = 每个游戏的sg用二进制表示的同时用(k+1)进制异或
为更具体地解释,我们编一道题:有n堆石子,分别有ai个石子,每次可以对最多k,最少1堆进行操作,即取走该堆任意个石子。两人轮流进行,取走最后一个石子的获胜。问是否先手必胜。
设sg[i]为第i堆的sg值。结合以前的经验,我们知道sg[i]=ai。我们依然求这n堆异或。异或可看做「不进位加法」,我们用每个数的二进制表示,进行(k+1)进制的「不进位加法」。举个例子,若三个数的二进制是
1010101
1010101
1010101
1111011
1111011
1111011
0010101
0010101
0010101假设k=2,即要三进制,那么相应三进制的异或为
2101210
2101210
2101210
为什么这么做呢?我认为,这样每个游戏对最高为的贡献最多为1,这样就可以保证SG=0时先手在取最多k个的情况下无法再次将SG变为0;SG>0的情况下,假设最高位数值为t,先手可以进行t个游戏使SG变为0。
anti-nim
反nim博弈。 anti-nim是有几堆石子,每次可以拿某一堆中的任意多个(不能不拿),谁取完最后一个石子谁「输」。
结论:
- 若每堆石子数=1,则xor之和为0必胜,否则必败
- 若有一堆>1,则xor之和非0必胜,否则必败
以下为我觉得正确的证明。
摘抄复制了一下一篇知乎上的回答。
奇异局势:所有堆xor之和为0的情况。
令S表示非奇异局势,T表示奇异局势;
规定一堆中石子数>1,则为充裕堆;=1,则为孤单堆。
S0:非奇异局势且充裕堆数为0;
S1:非奇异局势且充裕堆数为1;
S2:非奇异局势且充裕堆数为2;
T0:奇异局势且充裕堆数为0;
T2:奇异局势且充裕堆数为2;
(众所周知 T1不存在)
先考虑这5个状态的胜负。
无需多说,S0必败,T0必胜。
S1可转移到S0,因此S1必胜。
T2只能转移到S2或S1。若转移到S1,则T2必败;若转移到S2,则对方可再次转移到T2。因此T2为必败态,S2为必胜态。
现在,必胜:T0,S1,S2;
必败:S0,T2
接着,我们归纳一下:
当n>=2时,假设S1,S2,…,Sn都是必胜态,T2,T3,…,Tn都是必败态,由于T(n+1)只能转移到Sn或S(n+1),而S(n+1)可以转移到T(n+1)或T(n),因此T(n+1)是必败态,S(n+1)是必胜态。这样,除去S0,所有S都是必胜态;除去T0,所有T都是必败态。
丢一道例题:Be the Winner HDU - 2509
every-sg
基本形式:有n个博弈游戏同时进行,轮到他时必须玩所有还没结束的游戏。最后结束的游戏的输赢就是整个游戏的输赢。
这种题增加了一个性质:步数。
容易想到,每局游戏如果能赢,一定要赢,而且往后拖得越久越好;如果必输,一定输得越快越好。令ans为最后结束的那个游戏的步数,则ans为奇数时先手赢,偶数时后手赢。
s
t
e
p
(
当
前
状
态
)
=
{
0
已经输了
m
a
x
{
s
t
e
p
(
所
有
必
输
的
上
一
状
态
)
}
+
1
sg(当前状态)!=0
m
i
n
{
s
t
e
p
(
上
一
状
态
)
}
+
1
sg(当前状态)=0
step(当前状态)=\begin{cases} 0& \text{已经输了}\\ max\{step(所有必输的上一状态)\}+1& \text{sg(当前状态)!=0}\\ min\{step(上一状态)\}+1& \text{sg(当前状态)=0} \end{cases}
step(当前状态)=⎩⎪⎨⎪⎧0max{step(所有必输的上一状态)}+1min{step(上一状态)}+1已经输了sg(当前状态)!=0sg(当前状态)=0
翻硬币问题
基本形式:有一排硬币,从左到右分别标号1,2,…,两人轮流按一定限制翻硬币,但选择的最右边的硬币一定是从正面朝上翻到反面朝上,不能翻的人输。
结论:整个局面的sg等于每个朝上的硬币的sg的异或值
换句话说,令sg[i]为只有i号硬币朝上时的sg值,那么整个局面的sg为
s
g
[
a
1
]
⊕
s
g
[
a
2
]
⊕
.
.
.
⊕
s
g
[
a
k
]
sg[a_1] \oplus sg[a_2] \oplus ... \oplus sg[a_k]
sg[a1]⊕sg[a2]⊕...⊕sg[ak],其中ai号硬币朝上。
怎么理解呢?为更具体地表述,我们假设题目条件为每次可以翻转1个或2个硬币。
我们先求sg[i]。设硬币全反面朝上的状态为S0,只有第i号正面朝上为Si。显然sg[1]=1。S2可以转化成S0和S1,因此sg[2]=2。Sk可以通过翻1个转化为S0,也可以翻两个转化成Sj,1<=j<k,因此sg[k]=k。
现在可以这样想:假如i号硬币朝上,那么将它看做一堆石子,石子数目是i。
现在我们可以用已经求出的sg[i]求出整个局面的sg(简称SG)。假定SG>0。对于普通nim游戏,我们找到SG的二进制表示中1所在的最高位:第a位。假设sg[b]二进制的第a位为1,那么我们可以将有b个石子的这一堆(简称b堆)拿走一部分,使得SG=0。
对应到硬币,「将b堆拿完」即「将b号硬币由正面翻到背面」,「将b堆由原本的b个石子拿得只剩c个」即「将b号硬币由正面翻到背面,且将c号硬币翻转(不管是哪面朝上)」。
因此,这样的游戏,先求出sg[i](可以打表找规律),再求出SG。
例题:Daizhenyang’s Coin HDU - 3537(不知道为什么,我的代码总Compilation Error,明明用codeblocks和devc++都没问题的说)
树上删边
待做题
基本形式:有一棵树,给定根节点,两人轮流选择一条边,并将其及连带的子树删除,无法操作的输。
结论:叶子结点的sg=0,其余点的sg为「他的孩子的sg+1」的异或和
例题:A tree game HDU - 3094
与树上删边类似的是一种无向图删边,具体请看Christmas Game POJ - 3710。本题奇数边环可用一条边代替,偶数边环可用一个点代替。
不平等博弈
双方的操作是不同的。比如若干长宽为正整数的矩形,左方每次横着切,右方竖着切,要求切完后的两个矩形长宽都为正整数,谁不能切谁输。
法一:
这种题的一般做法是设置一个hp值,如n*1的矩形hp=n-1,1*m的矩形hp=-(m-1),我们是根据左方定的正负,hp为正代表对左方有利,为负代表对右方有利。假定每个矩形都有一个hp,那么当hp之和>0则左方必赢,<0则右方必赢,=0则后手必赢。
现在的重点就是hp怎么求了。每个矩阵都有且只有一个hp,它不会对双方都有利,也不会对双方有不利。
根据这一理念,先打表。
for(int i=1; i<N; ++i)
{
for(int j=1; j<N; ++j)
{
if(i==1) hp[i][j]=j-1;
else if(j==1) hp[i][j]=1-i;
else
{
for(int k=1; k<j; ++k)
{
hp[i][j]=max(hp[i][j],hp[i][k]+hp[i][j-k]+1);
}
for(int k=1; k<i; ++k)
{
hp[i][j]=min(hp[i][j],hp[k][j]+hp[i-k][j]-1);
}
}
}
}
然后就找规律,然后根据规律迅速求的任意一个矩阵的hp。。。。。在此我就不多说了,因为剩下的就和普通的博弈论相同了。
这道例题是Alice’s Game HDU - 3544。
法二:
有很多不平等博弈论,比如这道题,是可以用surreal number表示的。在此,我推荐Matrix67写的一篇相当漂亮的文章:实数、超实数和博弈游戏:数学的结构之美。这篇文章详细地介绍了surreal number的概念、运算、性质,很不容易理解,但我们只需要会用就够了。
待施工参考