( 1 ) (1) (1) 通过 S G SG SG函数的转移解决问题。
( 2 ) (2) (2) 寻找博弈模型
( 3 ) (3) (3) 对称建立优势
设 N N N为先手必胜态, P P P为后手必胜态。
S G SG SG 函数主要利用了其定义以判断当前的胜负状态。往往最终局面的 S G SG SG 函数值被设为 0 0 0,且当 S G SG SG 函数值为 0 0 0 时当前局面被认为是 P P P 状态,反之是一个 N N N 状态。这个结论是巧妙地和定义结合在一起的,因为若 ∀ S G ( v ) ≠ 0 ∀SG(v)≠0 ∀SG(v)̸=0,则 S G ( u ) = 0 SG(u)=0 SG(u)=0,对应了 P P P 状态的后继状态都是 N N N 状态;若 ∃ S G ( v ) = 0 ∃SG(v)=0 ∃SG(v)=0,则 S G ( u ) ≠ 0 SG(u)≠0 SG(u)̸=0,对应了一个 N N N 状态总有一个后继状态是 P P P 状态。
具体定义:
我们规定一个对于集合的操作 m e x mex mex,表示最小的不属于该集合的非负整数。 如: m e x { 0 , 1 , 2 } = 3 , m e x { 1 , 2 , 3 } = 0 , m e x { 0 , 1 , 3 } = 2 mex\{0,1,2\}=3,mex\{1,2,3\}=0,mex\{0,1,3\}=2 mex{0,1,2}=3,mex{1,2,3}=0,mex{0,1,3}=2;
定义 S G SG SG函数: S G ( x ) = m e x { S G ( y ) ∣ y SG(x)=mex\{ SG(y) | y SG(x)=mex{SG(y)∣y是 x x x的后继,也就是经过操作可以取得的剩下值 } \} }。
比如一堆石子,我们可以取任意个,那么 x x x个石子的石子的 S G SG SG值是多少呢?
可以知道, 0 0 0个石子 S G SG SG为 0 0 0,一的时候我们可以取一个,剩下 0 0 0,的 S G SG SG是 0 0 0,那么 m e x ( 0 ) mex(0) mex(0)就是 1 1 1,所以 1 1 1的 S G SG SG为 1 1 1。
递推下去当为x的时候我们可以取 1 − x 1-x 1−x个,那么剩下的值石子个数就是 x − 1 x-1 x−1到 0 0 0个,他的 m e x ( …   ) mex(\dots) mex(…)就是 x x x,所以这个例子的 x x x值的 S G SG SG值就是 x x x;
S G SG SG定理:
博弈的 S G SG SG 值是各个子博弈的 S G SG SG 值的 x o r xor xor。
问题原型:
给出n堆石子的数量,两人轮流从一堆中取出至少一个石子,先取完者获胜。
结论:
设 N N N为先手必胜态, P P P为后手必胜态。
当 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a i ⊕ ⋯ ⊕ a n = 0 a_1\oplus\ a_2\oplus\dots\oplus a_i\oplus\dots\oplus a_n =0 a1⊕ a2⊕⋯⊕ai⊕⋯⊕an=0 时,为 P P P态,否则为 N N N态。
证明:
证明等价于证明以下三个结论:
( 1 ) (1) (1) 证明空状态为 P P P。
( 2 ) (2) (2) 每一个 N N N都能通过取走一些石头而转化为 P P P。
( 3 ) (3) (3) P P P不能通过取走一些石头而转化为 P P P。
( 1 ) (1) (1) 显然,当 a 1 = a 2 = ⋯ = a n = 0 a_1=a_2=\dots=a_n=0 a1=a2=⋯=an=0时,后手必胜。
( 2 ) (2) (2) 当 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a i ⊕ ⋯ ⊕ a n = k a_1\oplus\ a_2\oplus\dots\oplus a_i\oplus\dots\oplus a_n =k a1⊕ a2⊕⋯⊕ai⊕⋯⊕an=k时,必定存在 a i a_i ai,使得 a i ⊕ k < a i a_i\oplus k<a_i ai⊕k<ai,此时只需要令 a i ′ = a i ⊕ k a_i'=a_i\oplus k ai′=ai⊕k,使得 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a i ′ ⊕ ⋯ ⊕ a n = 0 a_1\oplus\ a_2\oplus\dots\oplus a_i'\oplus\dots\oplus a_n =0 a1⊕ a2⊕⋯⊕ai′⊕⋯⊕an=0,此时由 N N N转化为 P P P。
( 3 ) (3) (3) 对于 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a i ⊕ ⋯ ⊕ a n = 0 a_1\oplus\ a_2\oplus\dots\oplus a_i\oplus\dots\oplus a_n =0 a1⊕ a2⊕⋯⊕ai⊕⋯⊕an=0且 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a i ′ ⊕ ⋯ ⊕ a n = 0 a_1\oplus\ a_2\oplus\dots\oplus a_i'\oplus\dots\oplus a_n =0 a1⊕ a2⊕⋯⊕ai′⊕⋯⊕an=0,由群相关结论很容易得出 a i = a i ′ a_i=a_i' ai=ai′,不符合规则。
以上得证。
例题:
下面是一个二人小游戏:桌子上有M堆扑克牌;每堆牌的数量分别为 n i ( i = 1 … m ) n_i(i=1\dots m) ni(i=1…m);两人轮流进行;每走一步可以任意选择一堆并取走其中的任意张牌;桌子上的扑克全部取光,则游戏结束;最后一次取牌的人为胜者。
现在我们不想研究到底先手为胜还是为负,我只想问大家:
——“先手的人如果想赢,第一步有几种选择呢?”
题解:
若 n 1 ⊕ n 2 ⊕ ⋯ ⊕ n i ⊕ ⋯ ⊕ n m = 0 n_1\oplus\ n_2\oplus\dots\oplus n_i\oplus\dots\oplus n_m =0 n1⊕ n2⊕⋯⊕ni⊕⋯⊕nm=0,则先手必输,输出0。
若 n 1 ⊕ n 2 ⊕ ⋯ ⊕ n i ⊕ ⋯ ⊕ n m = k n_1\oplus\ n_2\oplus\dots\oplus n_i\oplus\dots\oplus n_m =k n1⊕ n2⊕⋯⊕ni⊕⋯⊕nm=k,则输出满足 a i ⊕ k < a i a_i\oplus k<a_i ai⊕k<ai的 i i i的个数。
问题原型:
给出n堆石子的数量,两人轮流从一堆中取出至少一个石子,最后一个取的人输。
结论:
在反尼姆博奕中判断必胜局面的条件有两点,满足任意一点先手都能取胜,即必胜局面。
( 1 ) : (1): (1): 各堆石子数目异或结果不等于0,且存在有石子数目大于1的石子堆。
( 2 ) (2) (2): 所有石子堆均为1,且总堆数为偶数。
问题原型:
有n个阶梯呈升序排列,每个阶梯上有若干个石子,可行的操作是将一个阶梯上的石子移任意个(>0)到前一个台阶。当没有可行操作时(所有石子都被移动到了地面,即第0号台阶)输。
结论:
等价于奇数台阶上的 N i m Nim Nim博弈。
证明:
( 1 ) (1) (1) 如果对手移动偶数位上的石子,只需要将这些石子再向下移动一位。对结果无影响。
( 2 ) (2) (2) 将奇数位上的石子移动至偶数位,由结论 ( 1 ) (1) (1)可知,相当于将这些石子移除。
( 3 ) (3) (3) 由以上结论可得,阶梯博弈相当于奇数位上的 N i m Nim Nim博弈。
问题原型:
变种 ( 1 ) (1) (1):每次最多从一堆中取 k k k 个
变种 ( 2 ) (2) (2):每轮能取最多 k k k 堆,从这k堆中每堆中取数量任意的石子。(不同堆取石子的数量可以不同)
结论:
变种 ( 1 ) (1) (1):只需将每堆石子数对 ( k + 1 ) (k+1) (k+1)取模
变种 ( 2 ) (2) (2):设 a i a_i ai表示 a a a的二进制中的第 i i i位, b i b_i bi表示 b b b的二进制中的第 i i i位。只需定义 a ⊕ b = ( a + b )   m o d   ( k + 1 ) a\oplus b=(a+b)\bmod(k+1) a⊕b=(a+b)mod(k+1)。( 即: k = 1 k=1 k=1时, a ⊕ b = ( a + b )   m o d   2 a\oplus b=(a+b)\bmod 2 a⊕b=(a+b)mod2 )
证明:
与 N i m Nim Nim博弈类似。
问题原型:
N N N 枚硬币排成一排,有的正面朝上,有的反面朝上。我们从左开始对硬币按 1 1 1 到 N N N 编号。
第一,游戏者根据某些约束翻硬币,但他所翻动的硬币中,最右边那个硬币的必须是从正面翻到反面。例如,只能翻 3 3 3个硬币的情况,那么第三个硬币必须是从正面翻到反面。如果局面是正正反,那就不能翻硬币了,因为第三个是反的。
第二,谁不能翻谁输。
结论:
局面的 S G SG SG 值为局面中每个正面朝上的棋子单一存在时的 S G SG SG 值的异或和。即一个有 k k k个硬币朝上,朝上硬币位置分布在的翻硬币游戏中, S G SG SG值是等于 k k k个独立的开始时只有一个硬币朝上的翻硬币游戏的 S G SG SG值异或和。比如 T H H T T H THHTTH THHTTH这个游戏中, 2 2 2号、 3 3 3号、 6 6 6号位是朝上的,它等价于 T H 、 T T H 、 T T T T T H TH、TTH、TTTTTH TH、TTH、TTTTTH三个游戏和,即 s g [ T H H T T H ] = s g [ T H ] ⊕ s g [ T T H ] ⊕ s g [ T T T T T H ] sg[THHTTH]=sg[TH]\oplus sg[TTH]\oplus sg[TTTTTH] sg[THHTTH]=sg[TH]⊕sg[TTH]⊕sg[TTTTTH]。我们的重点就可以放在单个硬币朝上时的 S G SG SG值的求法。
例题:
在各种具体约束条件下的翻硬币博弈求解:博弈-翻硬币游戏 。
问题原型:
( 1 ) (1) (1)
在 n + 1 n+1 n+1行和 m + 1 m+1 m+1列的棋盘上,坐标从 ( 0 , 0 ) (0,0) (0,0)到 ( n , m ) (n,m) (n,m),每个格子有一枚硬币。两个玩家轮流操作,每次同时翻转同一列或者同一行的两枚硬币。且:横纵坐标最大的那枚硬币必须是由正面翻到反面。
两边轮流操作直至一方无法操作,无法操作的判负。
( 2 ) (2) (2)
在 n + 1 n+1 n+1行和 m + 1 m+1 m+1列的棋盘上,坐标从 ( 0 , 0 ) (0,0) (0,0)到 ( n , m ) (n,m) (n,m),每个格子有一枚硬币。两个玩家轮流操作,每次同时翻转在一个矩形四个顶点上的硬币,并且要求,每次操作时,矩形横纵坐标最大的格子中的硬币必须是由正面翻到反面。两边轮流操作直至一方无法操作,无法操作的判负。
( 3 ) (3) (3)
三维棋盘,其余与 ( 2 ) (2) (2)类似。
结论:
( 1 ) (1) (1) S G ( x , y ) = x ⊕ y SG(x,y)=x\oplus y SG(x,y)=x⊕y。
( 2 ) (2) (2) S G ( x , y ) = x ⊗ y SG(x,y)=x\otimes y SG(x,y)=x⊗y
( 3 ) (3) (3) S G ( x , y , z ) = x ⊗ y ⊗ z SG(x,y,z)=x\otimes y\otimes z SG(x,y,z)=x⊗y⊗z
⊗ \otimes ⊗实现代码:
int m[2][2]={0,0,0,1};
int Nim_Multi_Power(int x,int y) //辅助函数
{
if(x<2)
return m[x][y];
int a=0;
for(;;a++)
if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
break;
int m=1<<(1<<a);
int p=x/m,s=y/m,t=y%m;
int d1=Nim_Multi_Power(p,s);
int d2=Nim_Multi_Power(p,t);
return (m*(d1^d2))^Nim_Multi_Power(m/2,d1);
}
int Nim_Multi(int x,int y) //求解函数
{
if(x<y)
return Nim_Multi(y,x);
if(x<2)
return m[x][y];
int a=0;
for(;;a++)
if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
break;
int m=1<<(1<<a);
int p=x/m,q=x%m,s=y/m,t=y%m;
int c1=Nim_Multi(p,s);
int c2=Nim_Multi(p,t)^Nim_Multi(q,s);
int c3=Nim_Multi(q,t);
return (m*(c1^c2))^c3^Nim_Multi_Power(m/2,c1);
}
问题原型:
在某一棵树上删除一条边,同时删去所有在删除后不再与根相连的部分
双方轮流操作,先删除完者获胜。
结论
为了更好理解该博弈模型,我们引入“竹子”的概念:
根据上面的游戏规则,拿掉竹子上的某一节,那么此节上面的部分都会被删除。这就是Nim博弈的变形。其对应的 S G [ x ] = x SG[x]=x SG[x]=x。
我们把竹子的形态变的稍微复杂一点,在竹子上加一些分支,就可以得到一棵朴素的树。
首先介绍克朗原理:
克朗原理:
对于树上的某一个点,ta的分支可以转化成以这个点为根的一根竹子,这个竹子的长度就是ta各个分支的边的数量的异或和。
举例:
在这棵树中,其 S G SG SG函数值为 8 8 8。
我们可以得到类似的结论: S G [ x ] = 0 SG[x]=0 SG[x]=0时,后手必胜,否则先手必胜。
问题原型:
类似树上删边,在某一幅无向图上删除一条边,同时删去所有在删除后不再与根相连的部分 。双方轮流操作,先删除完者获胜。
结论:
例图:
我们当然希望把上图也转化成一个树形结构,之后利用克朗原理转化成竹子,变成Nim博弈解决 。
首先介绍费森原理:
费森原理
环上的点可以融合,且不改变图的 S G SG SG值。
可以发现,上图中门是独立于整个大框外的,所以我们从门开始。
首先,我们可以把地板上的两个点视为一个,因为地板本身就可以看成是一个大点
这样这扇门就变成一个三角形(一个有三个点的环)
费森原理指出,我们可以把环上一个点等价成一个自环,而这个环又可以变成一条边
一般来说 :
我们可以把一个带有奇数边的环等价成只有一个端点的一条边 ,
而偶数边的环等价于一个点。
有了这个结论,就简单多了
因此,上图中房子的烟囱和窗户都可以等价成一个点
那我们继续我们的化简:
从上面所有的讨论中,我们可以得到启发:
对于博弈的大部分问题,只要 S G SG SG值相同,就可以互相转化。
问题原型:
由 n n n个游戏同时进行,除非游戏结束,否则必须操作。取最后一次的获胜情况为结果。
结论:
这个整体博弈的思路是:如果某个子游戏自己必胜,使游戏总步数尽量多。如果必败,使游戏总步数尽量少。
对于该博弈,先手必胜当且仅当所有子博弈中的最大的 s t e p step step为奇数。
实现:
对于一个子游戏的情况 v v v,如果 S G ( v ) = 0 SG(v)=0 SG(v)=0,我们需要知道其最快几步能将状态转化为终止状态。如果 S G ( v ) ≠ 0 SG(v)\ne0 SG(v)̸=0,我们需要知道其最快几步能将状态转化为终止状态。我们用 s t e p ( v ) step(v) step(v)表示这个值。则:
s t e p ( v ) = { 0 v 为终止态 max { s t e p ( u ) } + 1 S G ( v ) ≠ 0 且 S G ( u ) = 0 min { s t e p ( u ) } + 1 S G ( v ) = 0 且 S G ( v ) = 0 step(v)=\left\{\begin{aligned} &0&v\text{为终止态} \\&\max\{step(u)\}+1&SG(v)\ne0\text{且}SG(u)=0 \\&\min\{step(u)\}+1&SG(v)=0\text{且}SG(v)=0 \end{aligned}\right. step(v)=⎩⎪⎨⎪⎧0max{step(u)}+1min{step(u)}+1v为终止态SG(v)̸=0且SG(u)=0SG(v)=0且SG(v)=0、
其中 u u u为 v v v的后继状态。
这一类问题中, S G SG SG 函数的用法显而易见,也有很多很多问题可以转化为此类问题。
在这一类问题中,前驱与后继状态清晰明了,而且往往没有显然的规律,以至于出题人会给你充足的时间让你把各种起手的状态处理一遍。这时就要用到 S G SG SG 函数了,而且很显然是让你把起手时的 S G SG SG 函数值推出来存下来 …… 于是就可以将其他的一些问题也对应到 D A G DAG DAG 上,然后直接通过 S G SG SG 函数之间的转移而解决几乎全部的问题。(即:打表找规律)
问题原型:
给出两堆石子的数量,两人轮流从一堆取出至少一个或同时从两堆中取出相同数量的石子,先取完者获胜。
结论:
我们用 ( a i , b i ) (a_i,b_i) (ai,bi)表示两堆石子的数量,并称其为“局势”。将后手必赢的局势称为奇异局势。
奇异局势有: ( 0 , 0 ) , ( 1 , 2 ) , ( 3 , 5 ) , ( 4 , 7 ) , ( 6 , 10 ) , ( 8 , 13 ) , ( 9 , 15 ) , ( 11 , 18 ) , … , ( a k , b k ) (0,0),(1,2),(3,5),(4,7),(6,10),(8,13),(9,15),(11,18),\dots ,(a_k,b_k) (0,0),(1,2),(3,5),(4,7),(6,10),(8,13),(9,15),(11,18),…,(ak,bk)。(排列规则为 b i ⩾ a i b_i\geqslant a_i bi⩾ai 且 a i a_i ai增序排列)
我们发现奇异局势有如下特点:
( 1 ) (1) (1) a k a_k ak为前 k − 1 k-1 k−1 个奇异局势中未曾出现过的最小正整数。
( 2 ) (2) (2) 对于第 k k k 个奇异局势 ( a k , b k ) (a_k,b_k) (ak,bk), b k − a k = ( k − 1 ) b_k-a_k=(k-1) bk−ak=(k−1)。
( 3 ) (3) (3) a k = ( b k − a k ) ∗ 0.618 a_k=(b_k-a_k)*0.618 ak=(bk−ak)∗0.618。
证明:
略。
问题原型:
有一堆个数为 n n n的石子,游戏双方轮流取石子,满足:
1 ) 1) 1) 先手不能在第一次把所有的石子取完;
2 ) 2) 2) 之后每次可以取的石子数介于 1 1 1 到对手刚取的石子数的 2 2 2倍 之间(包含 1 1 1 和对手刚取的石子数的 2 2 2 倍)。
约定取走最后一个石子的人为赢家。
结论:
先手获胜当且仅当 n n n不是斐波那契数。
证明:
( 1 ) (1) (1) 先证明当 n n n为斐波那契数时,先手必败。
n = f i b ( 2 ) n=fib(2) n=fib(2) 时,显然先手必败。
假设 n ⩽ f i b ( k ) n\leqslant fib(k) n⩽fib(k) 时,结论成立。则 n = f i b ( k + 1 ) n=fib(k+1) n=fib(k+1) 时, n n n可分解为 f i b ( k ) + f i b ( k − 1 ) fib(k)+fib(k-1) fib(k)+fib(k−1)。由斐波那契数列的性质可得, f i b ( k ) ⩾ 2 ∗ f i b ( k − 1 ) fib(k)\geqslant 2*fib(k-1) fib(k)⩾2∗fib(k−1),所以先手取得石子数一定小于 f i b ( k − 1 ) fib(k-1) fib(k−1),否则后手能一次全部取完。有假设可得,在 n = f i b ( k − 1 ) n=fib(k-1) n=fib(k−1)的情况时,后手能取走最后一颗石子。所以在这种情况下,后手一定能取完 f i b ( k − 1 ) fib(k-1) fib(k−1)这一部分石子。此时,剩余量为 f i b ( k ) fib(k) fib(k)颗石子,且显然先手无法一次全都取完。再由假设可得,此时一定是后手取走最后一颗石子。所以先手必败。
( 2 ) (2) (2) 证明先手必胜的情况。
由齐肯多夫定理( Z e c k e n d o r f Zeckendorf Zeckendorf定理)可知,任意正整数都能表示成若干不相邻的斐波那契数之和。
令 n = f i b ( a 1 ) + f i b ( a 2 ) + ⋯ + f i b ( a p ) n=fib(a_1)+fib(a_2)+\dots +fib(a_p) n=fib(a1)+fib(a2)+⋯+fib(ap)。( a 1 < a 2 < ⋯ < a p a_1<a_2<\dots <a_p a1<a2<⋯<ap)
由斐波那契数列性质可得, f i b ( k ) > 2 ∗ f i b ( k − 2 ) fib(k)>2*fib(k-2) fib(k)>2∗fib(k−2),此时,先手只要取走 f i b ( a 1 ) fib(a_1) fib(a1)颗石子,由于 a 1 , a 2 , … , a p a_1,a_2,\dots,a_p a1,a2,…,ap不连续,所以后手方取的石子数一定小于 f i b ( a 2 ) fib(a_2) fib(a2),由证明 ( 1 ) (1) (1)得,对于 f i b ( a 2 ) fib(a_2) fib(a2) 个石子,后手(该情况下的先手)一定能取到最后一个。以此递推,先手一定能取到最后一个石子。
问题原型:
有一堆个数为 n n n的石子,游戏双方轮流取石子,满足:
1 ) 1) 1) 先手不能在第一次把所有的石子取完;
2 ) 2) 2) 之后每次可以取的石子数介于 1 1 1 到对手刚取的石子数的 k k k 倍之间(包含 1 1 1和对手刚取的石子数的 k k k 倍)。
约定取走最后一个石子的人为赢家。
结论:
k = 1 k=1 k=1 时,先手必胜当且仅当 n n n 不是 2 2 2 的次幂。否则,先手只要不停取 l o w b i t ( n ) lowbit(n) lowbit(n)即可取胜。
k = 2 k=2 k=2 时,等同于斐波那契博弈。
k = 3 k=3 k=3 时,构造数列 a ( n ) a(n) a(n),使得其满足如下性质:
对于任意整数 n n n, n n n可分解为 a ( m 1 ) + a ( m 2 ) + ⋯ + a ( m p ) a(m_1)+a(m_2)+\dots +a(m_p) a(m1)+a(m2)+⋯+a(mp)。且对于任意 i i i, a ( m i ) > k ∗ a ( m i + 1 ) a(m_i)>k*a(m_i+1) a(mi)>k∗a(mi+1)。
此时,模仿斐波那契博弈,先手必胜当且仅当 n n n不属于数列 a ( n ) a(n) a(n)。
证明:
同斐波那契博弈。
代码实现:
设数组 a [ ] , b [ ] a[],b[] a[],b[]。
a [ i ] a[i] a[i] 表示这个数列的第 i i i个数, b [ i ] b[i] b[i] 表示用( a [ 1 ] , a [ 2 ] , … , a [ i ] a[1],a[2],\dots ,a[i] a[1],a[2],…,a[i])所能构造出来的最大的数。
显然, a [ i + 1 ] = b [ i ] + 1 a[i+1]=b[i]+1 a[i+1]=b[i]+1, b [ i + 1 ] = a [ i + 1 ] + b [ j ] b[i+1]=a[i+1]+b[j] b[i+1]=a[i+1]+b[j],其中 j j j 为最大的满足 a [ j ] ∗ k < a [ j + 1 ] a[j]*k<a[j+1] a[j]∗k<a[j+1]的数。
a[0]=0;a[1]=1;b[0]=0;b[1]=1;
int i=1;
while(a[i]<n){
a[i+1]=b[i]+1;
int j=0;
while(a[j+1]*k<a[i+1])j++; //这里注意必须从小往大找,不然会TLE
b[i+1]=a[i+1]+b[j];
idex++;
}
例题:
有 n n n个硬币,将它们围成一个圈。两人轮流翻转至多k个连续的硬币,翻转完者胜。
题解:
( 1 ) (1) (1) 若 k = 1 k=1 k=1,显然奇数先手赢,偶数后手赢。
( 2 ) (2) (2) 若 k ⩾ 2 : k\geqslant 2: k⩾2:
a : a: a: 先手一次取完,先手赢。
b : b: b: 先手不能一次取完,后手只要将剩余部分分为相等两部分,建立对称优势,后手必胜。
问题原型:
玩家进行 k k k次某种游戏,第 i i i次的败者,将会作为第 i + 1 i+1 i+1次的先手进行这个游戏。第 k k k次游戏的赢家才是整个游戏的赢家。
结论:
定义四种状态:先手必胜、先手必败、先手可决定输赢、先手不能控制。
若游戏先手必败或先手不能控制,则后手只要一直胜利就可以取得最终胜利。
若游戏先手必胜,则若 k k k为偶数,则整个游戏后手必胜,若 k k k为奇数,则整个游戏先手必胜。
若游戏先手可决定输赢,则先手只要一直输到最后一局,再赢下去,就能获得游戏胜利。先手必胜。
例题:
有一种游戏:给定 n n n个非空串。两个玩家轮流向一个空字符串后面加字母。每次操作形成的新字符串一定要是这 n n n个串中某一个的前缀,如果无法做到,就输了。
玩家玩 k k k次这样的游戏,第 i i i次的败者,将会作为第 i + 1 i+1 i+1次的先手进行这个游戏。第 k k k次游戏的赢家才是整个游戏的赢家。
题解:
先建立字符串的Trie树。
叶子结点为先手必败态;
若某结点的所有儿子都是先手必败态,则该结点为先手必胜态;
若某结点的所有儿子都是先手必胜态,则该结点为先手必败态;
若某结点的儿子既有先手必胜态,又有先手必败态,或者是存在先手不能控制态,则该状态为先手可决定输赢;
若某结点的所有儿子都是先手可决定输赢,则该结点为先手不能控制。
若某结点的儿子除了可输可赢态外还有其他状态,那么就当可输可赢态不存在。因为,不能将主导权交给对手。
暂无。待补充。