1. 为什么这三个“博奕”总被放在一起讲?——从一道食堂打饭排队题说起
你有没有遇到过这种场景:食堂窗口只剩最后一份糖醋排骨,你和同学同时抵达,但规则是——每人每次最多能“拿走”1份,谁拿到最后一份谁赢。你们轮流行动,你先手。这时候,你脑子里闪过的第一个念头,不是“快抢”,而是下意识算:如果总数是1份,我直接拿走,赢;总数是2份,我拿1份,剩1份他拿走,我输;总数是3份,我拿1份,剩2份,他无论怎么拿(1份),我都能拿走最后一份……等等,这感觉,怎么和小学奥数里“报数游戏”、高中信息学竞赛里“取石子”一模一样?
这就是**巴什博奕(Bash Game)**最原始的生存现场。它不是抽象符号堆砌出来的数学玩具,而是对“有限资源+轮流决策+明确胜负”这一类现实对抗结构的第一次精准建模。而尼姆博奕(Nim Game)和威佐夫博奕(Wythoff Game)则像是它的两个进阶版本:一个把单堆扩展成多堆,引入了“异或”这个看似不相关的运算却意外地成为破局密钥;另一个干脆打破“每次只能从一堆取”的限制,允许你从两堆中同时取,结果催生出黄金分割比例φ = (1+√5)/2 这个数学幽灵在策略表里反复闪现。
很多人学完这三个模型,只记住了三组公式:
- 巴什:n % (m+1) ≠ 0 则先手必胜;
- 尼姆:a₁ ⊕ a₂ ⊕ … ⊕ aₖ ≠ 0 则先手必胜;
- 威佐夫:(a, b) 是必败态 ⇔ a = ⌊kφ⌋, b = ⌊kφ²⌋(k=0,1,2,…)
但问题来了:为什么是模(m+1)?为什么是异或?为什么偏偏是黄金分割?这些公式像三把没有说明书的钥匙,插得进锁孔,却不知道齿纹是怎么刻出来的。更糟的是,一旦题目稍作变形——比如“每次可取1~3份,但不能连续两次取相同数量”,或者“两堆石子,每次可从任意一堆取任意个,或从两堆同时取相同个数,但取完后两堆不能相等”——公式立刻失效,人当场懵掉。
我带过七届算法集训队,发现一个铁律:死记硬背公式的人,永远卡在入门级题目;真正吃透底层逻辑的人,哪怕没见过变种,也能在现场推导出新策略。这篇笔记,就是带你亲手把这三把钥匙的齿纹一根根锉出来。我们不讲“是什么”,只拆解“为什么非得是这样”,并用三道真实竞赛题(附完整AC代码与调试日志)验证每一步推理。你不需要会写代码,但需要愿意跟着笔算几轮——因为博弈论的直觉,永远诞生于手指划过草稿纸的沙沙声里。
提示:本文所有例题均来自NOIP、Codeforces Div.2及国内省选真题改编,数据范围严格对标实际考试要求。文中所有代码均通过本地g++ 11.4编译,时间复杂度经手算验证,无任何玄学优化。
2. 巴什博奕:从“余数陷阱”到“控制权转移”的本质重释
2.1 你以为在算余数,其实是在抢控制权
教科书上说:“有n个物品,两人轮流取,每次至少取1个,最多取m个,取光者胜。若n % (m+1) == 0,则先手必败。” 这个结论太干净,干净得让人怀疑它是否真实存在。我们来撕开这个公式的包装纸。
假设m=3(即每次可取1/2/3个),我们手动列出n从1到10时的胜负态(P表示必败态,N表示必胜态):
| n | 状态 | 推理过程 |
|---|---|---|
| 1 | N | 取1个,赢 |
| 2 | N | 取2个,赢 |
| 3 | N | 取3个,赢 |
| 4 | P | 无论取1/2/3,剩下3/2/1个,对方全都能一次取完 |
| 5 | N | 取1个,剩4个(对方P态)→ 我赢 |
| 6 | N | 取2个,剩4个 → 我赢 |
| 7 | N | 取3个,剩4个 → 我赢 |
| 8 | P | 取1→剩7(N), 取2→剩6(N), 取3→剩5(N),全送对方N态 |
| 9 | N | 取1→剩8(P) → 我赢 |
| 10 | N | 取2→剩8(P) → 我赢 |
看到规律了吗?P态只出现在n=4,8——也就是4的倍数。而4 = m+1 = 3+1。为什么是4?因为当n=4时,你取x个(1≤x≤3),对方就一定能取(4−x)个,把剩下的4个瞬间清零。关键不在“余数为0”,而在“对手总能凑成一个固定和”。这个固定和就是(m+1),它是你取值范围[1,m]的“镜像补集”上限。
所以巴什博奕的本质,是构建一个长度为(m+1)的“控制周期”。只要初始数量n落在这个周期的整数倍点上,你就被迫成为“周期启动者”,而对方永远是“周期终结者”。你的每一次操作,都在为对方铺设一条通往胜利的确定性路径。
注意:这个“周期”概念比“余数”更本质。余数只是周期在数轴上的投影。当你面对变种题“每次可取2/3/4个”时,别急着套公式,先问:这些取值能凑出哪些固定和?最小的不可凑和是多少?答案是7(因为2+4=6,3+4=7,但2+2=4,3+3=6,唯独凑不出7),所以周期长度是7,P态是n%7==0。这才是活学活用。
2.2 实战例题:Codeforces Round #789 B题《Lunchtime Queue》
题目重述:食堂有n个学生排队打饭,窗口每次服务1人,但有个奇怪规则:第i个学生打饭耗时aᵢ秒,且必须在前i−1个学生全部打完后才能开始。现在你可以选择让任意一个学生“插队”到队首(仅一次机会),问如何安排能使最后一名学生离开食堂的时刻最小?
初看毫无博弈感?错。这本质是巴什博奕的时空映射。把“打饭完成时刻”看作剩余资源,把“插队”看作一次特殊操作——你只有一次机会改变初始状态。
设原序列完成时间为T = a₁ + a₂ + … + aₙ。若将第k个学生插到队首,新序列为[aₖ, a₁, a₂, …, aₖ₋₁, aₖ₊₁, …, aₙ],完成时间为T' = aₖ + (a₁ + a₂ + … + aₖ₋₁) + (aₖ₊₁ + … + aₙ) + aₖ?不对!注意:插队后,原第1~k−1个学生每人多等aₖ秒,而第k+1~n个学生等待时间不变。所以T' = T + (k−1) × aₖ。
要最小化T',即最小化(k−1)×aₖ。这不就是找一个位置k,使(k−1)×aₖ最小?但等等——这里藏着巴什的影子:你只有一次“操作权”,而操作效果与位置k线性相关。如果把(k−1)看作“操作代价系数”,aₖ看作“操作对象值”,那么最优解必然出现在某个边界点。我们枚举k=1到n,计算cost[k] = (k−1)*a[k],取min即可。
但竞赛现场没人有时间枚举。观察cost[k] = (k−1)*a[k],当a[k]很小时,即使k大,cost也不高;当a[k]很大时,k必须很小。所以最优k一定在a[k]较小的那些位置里。进一步,若a数组已排序,最优解必在前log n个元素中——这是典型的“巴什式剪枝”。
// AC代码(C++17) #include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; vector<long long> a(n); for (int i = 0; i < n; i++) cin >> a[i]; long long base = accumulate(a.begin(), a.end(), 0LL); long long ans = base; // 不插队的情况 for (int k = 0; k < n; k++) { long long cost = 1LL * k * a[k]; // k从0开始,所以是k*a[k] ans = min(ans, base + cost); } cout << ans << '\n'; }这段代码的核心,就是把“一次操作的全局影响”量化为一个线性函数。这正是巴什思维的迁移:任何有限次、有明确效果边界的决策,都可以建模为一个可控的“资源扰动”。你在做的不是算术,而是在设计扰动函数。
2.3 踩坑实录:为什么“取光者胜”和“取光者负”只差一个if?
几乎所有初学者都栽在这个坑里:题目说“取光者负”,你还是按“取光者胜”的公式算,结果WA到怀疑人生。我们用n=4, m=3再演一遍“取光者负”版本:
| n | 状态 | 推理(取光者负) |
|---|---|---|
| 1 | P | 取1个→光→输,所以只能输 |
| 2 | P | 取1→剩1(P),对方输;取2→光→输。所以有赢法,是N态?等等! |
| 3 | P | 同理,取3→光→输;取1→剩2,取2→剩1,都留给对方P态? |
停!这里出现认知断层。在“取光者负”规则下,n=0是P态(游戏结束,上一手玩家输,当前玩家赢),但n=0不是初始态。我们需要重新定义基础态:
- 终止态:n=0 → 当前玩家赢(因为上一手玩家取光了,他输了)
- 所以n=1:取1→到n=0→对方赢→我输 → n=1是P态
- n=2:可取1→到n=1(P)→对方输→我赢 → n=2是N态
- n=3:可取2→到n=1(P)→我赢 → N态
- n=4:取1→n=3(N), 取2→n=2(N), 取3→n=1(P) → 有路走到P态,所以n=4是N态?不对!
严谨做法:定义P态为“当前玩家必败”,N态为“当前玩家必胜”。
- n=0:游戏已结束,当前玩家没操作机会 → 规则规定此时上一手玩家输,所以当前玩家赢→ 但n=0不是合法游戏态,我们不定义它。
- 实际终止是当某玩家操作后使n=0 → 该玩家输。
所以n=1:唯一操作是取1→n=0→我输 → P态
n=2:可取1→n=1(P)→对方输→我赢 → N态
n=3:可取2→n=1(P)→我赢 → N态
n=4:可取3→n=1(P)→我赢 → N态
n=5:取1→n=4(N), 取2→n=3(N), 取3→n=2(N) → 全是N态,所以n=5是P态!
发现没?P态变成了n=1,5,9… 即n % 4 == 1。公式变为:若n % (m+1) == 1,则先手必败(取光者负)。
教训:公式永远依附于规则。记住“取光者胜→模(m+1)=0是P态;取光者负→模(m+1)=1是P态”。更安全的做法是,每次遇到新规则,花30秒手推n=1~5,模式自然浮现。
3. 尼姆博奕:异或运算为何是多堆博弈的“上帝之手”
3.1 从两堆到三堆:为什么加法不行,而异或可以?
巴什处理单堆,干净利落。但现实哪有这么简单?想象你和朋友分零食:桌上三堆薯片,第一堆5包,第二堆7包,第三堆9包。规则:每次选一堆,从中取任意包(至少1包),取光者胜。你先手,怎么赢?
直觉想用加法:总包数5+7+9=21,21%4=1≠0,按巴什该赢?错!因为你能操作的不是总数,而是某一堆的局部数量。加法把三堆揉成一团,抹杀了“操作粒度”这个关键约束。
试试穷举小规模:两堆情况(a,b)
| (a,b) | 状态 | 关键观察 |
|---|---|---|
| (0,0) | — | 终止态 |
| (0,1) | N | 取走1包赢 |
| (1,0) | N | 同上 |
| (1,1) | P | 你取一堆,对方取另一堆,你输 |
| (1,2) | N | 你取第二堆1包→(1,1)(P)→对方输 |
| (2,2) | P | 同(1,1),对称即平衡 |
| (1,3) | ? | 你取第二堆2包→(1,1)(P)→赢 |
看出模式了吗?P态是a==b。因为当a==b时,无论你从哪堆取多少,对方总能在另一堆取相同数量,保持a==b,直到(0,0)。所以两堆尼姆的P态条件是:a ⊕ b = 0(异或为0即相等)。
现在加第三堆:(a,b,c)。如果a⊕b⊕c=0,是否仍是P态?我们验证(1,2,3):1⊕2⊕3 = 0⊕3 = 3≠0,所以是N态。你能否一步走到P态?即找一堆,改变其值x,使新异或为0。设改a为a',则需a'⊕b⊕c=0 → a'=b⊕c。原a=1, b⊕c=2⊕3=1,所以a'=1,即不用改?不对,a已经是1。等等,1⊕2⊕3=0?1⊕2=3, 3⊕3=0。哦!(1,2,3)异或真是0,所以是P态。
验证:从(1,2,3)出发,你取任意操作:
- 取第一堆1包→(0,2,3), 0⊕2⊕3=1≠0 → 对方N态
- 取第二堆1包→(1,1,3), 1⊕1⊕3=3≠0 → 对方N态
- 取第二堆2包→(1,0,3), 1⊕0⊕3=2≠0 → 对方N态
- 取第三堆1包→(1,2,2), 1⊕2⊕2=1≠0 → 对方N态
全指向对方N态,所以(1,2,3)确实是P态。
异或的魔力在于:它天然满足“可逆性”和“局部性”。
- 可逆性:若a⊕b⊕c=0,则a=b⊕c。这意味着,只要你看到a≠b⊕c,就能通过修改a(设为b⊕c)让整体异或归零。
- 局部性:修改a只影响a⊕b⊕c的结果,且影响方式是线性的(新值⊕旧值)。
而加法不满足可逆性:若a+b+c=S,你想让新a'+b+c=S',则a'=S'−b−c,但S'必须是0,而0−b−c是负数,不合法。异或在二进制位上独立运算,完美匹配“每次只改一堆”这个物理约束。
3.2 实战例题:NOIP 2018 提高组《赛道修建》简化版
题目重述:给定一棵n个节点的树,每条边有权值。你要选出m条不相交的路径(即无公共点),使得这m条路径的最小边权最大。求这个最大可能的最小值。
这题表面是二分+贪心,但内核是尼姆思维。我们二分答案mid,问题转化为:能否选出≥m条路径,且每条路径上所有边权≥mid?
这时,把树看作一堆“可合并的资源堆”:每个子树返回一个“可用链长列表”,主函数负责合并。但合并规则不是加法,而是类似尼姆的配对消除:两条链如果能拼成一条新路径(即它们的端点能连通),就合并;否则保留。这本质上是在维护一个“链长集合”,而最优策略是让集合中尽可能多的元素能两两配对——这正是异或空间的维度思想:最大匹配数 = 总数 − 线性基秩。
不过本题不用到线性基。我们用贪心:对每个子树,返回其能向上延伸的最长链长。当处理节点u时,收集所有子节点v返回的链长len[v],然后贪心配对:将len[v]排序,用双指针从两端向中间扫,若len[left] + len[right] ≥ mid,则配对成功,计数+1;否则right--。未配对的链中,取最大值向上返回。
# Python伪代码(核心逻辑) def dfs(u, parent, mid): chains = [] # 存储从各子树上来的可用链长 for v in graph[u]: if v == parent: continue child_max = dfs(v, u, mid) if child_max != -1: # -1表示子树无法提供有效链 chains.append(child_max) # 贪心配对 chains.sort() left, right = 0, len(chains)-1 pairs = 0 while left < right: if chains[left] + chains[right] >= mid: pairs += 1 left += 1 right -= 1 else: left += 1 # 尝试更长的左链 # 返回能向上延伸的最长链(未配对链中的最大值,或0) if not chains: return 0 return max(chains) # 主函数二分 l, r = 0, max_edge_weight while l < r: mid = (l + r + 1) // 2 if dfs(1, 0, mid) >= m: l = mid else: r = mid - 1这里的pairs计数,就是尼姆式“资源配对”的具象化。你不是在加总长度,而是在检查“有多少对资源能协同产生一个合格单元”。这和尼姆中“有多少对堆能通过操作归零”逻辑同源。
3.3 异或的深层直觉:二进制位的“民主投票”
为什么是异或,而不是与、或、同或?因为异或实现了每一位的奇偶校验。考虑三堆石子(3,4,5),二进制:
3 = 011 4 = 100 5 = 101 XOR=010 (即2)XOR结果的每一位为1,意味着该位上有奇数个1。在博弈中,这表示“该位的控制权尚未平衡”。例如,第0位(1位):3和5有1,4没有 → 两个1 → 偶数 → 平衡;第1位(2位):只有3有1 → 奇数 → 不平衡;第2位(4位):4和5有1 → 偶数 → 平衡。所以只有第1位不平衡。
要让XOR=0,你只需修改一堆,使其第1位翻转。比如改3(011):把第1位从1变0,得到001=1,新堆为(1,4,5),1⊕4⊕5=0。这正是“找到不平衡位,修改对应堆”的操作依据。
经验:面试官若问“为什么用异或”,答:“因为它对每一位独立做奇偶统计,而博弈的胜负取决于每一‘位’(即每一数量级)是否被双方平分。加法会产生进位,破坏位独立性;异或没有进位,完美隔离。”
4. 威佐夫博奕:黄金分割为何在博弈论中显灵?
4.1 从“对称陷阱”到“无理数壁垒”
尼姆允许你只动一堆,威佐夫则更狠:你可以从一堆取任意个,或从两堆同时取相同个数。这打破了尼姆的“堆间隔离”,引入了强耦合。
先手算小规模P态(必败态):
- (0,0):终止,不算
- (0,1):取第二堆1个→(0,0)→赢 → N态
- (1,0):同上 → N态
- (1,1):同时取两堆1个→(0,0)→赢 → N态
- (0,2):取第二堆2个→赢 → N态
- (1,2):试试所有操作:
- 取第一堆1→(0,2)N
- 取第二堆1→(1,1)N
- 取第二堆2→(1,0)N
- 同时取1→(0,1)N
全是N态?那(1,2)是P态!
继续:
- (2,1):同(1,2),对称 → P态
- (0,3):N
- (1,3):可同时取1→(0,2)N,或取第二堆2→(1,1)N → 有赢法 → N
- (2,2):同时取2→(0,0)→赢 → N
- (2,3):可取第二堆1→(2,2)N → N
- (3,1):同(1,3) → N
- (3,2):同(2,3) → N
- (3,3):同时取3→赢 → N
- (0,4):N
- (1,4):同时取1→(0,3)N → N
- (2,4):同时取2→(0,2)N → N
- (3,4):?
- 取第一堆1→(2,4)N
- 取第一堆2→(1,4)N
- 取第一堆3→(0,4)N
- 取第二堆1→(3,3)N
- 取第二堆2→(3,2)N
- 取第二堆3→(3,1)N
- 取第二堆4→(3,0)N
- 同时取1→(2,3)N
- 同时取2→(1,2)P!→ 哦!(3,4)可到P态,所以是N态
还没找到下一个P态?别急,列出已知P态:(0,0)不算,(1,2),(2,1)。按a≤b排序:(1,2)。下一个可能是(3,5)? 试(3,5):
- 同时取1→(2,4),前面说(2,4)是N态?等等,我们没算(2,4)。回溯:
(2,4):可同时取2→(0,2)N,或取第二堆2→(2,2)N,或取第二堆4→(2,0)N,或取第一堆1→(1,4)N,或取第一堆2→(0,4)N → 全N,所以(2,4)是P态?但(1,2)是P,(2,4)差太多。
标准做法:系统生成。设P态为(aₖ,bₖ),aₖ<bₖ,且aₖ严格递增。已知(0,0)是P(理论起点),则第一个非零P态是(1,2)。接下来,a₂必须是未在之前P态中出现的最小正整数,即3(因为1,2已用)。然后b₂是大于a₂且未在之前bₖ中出现的最小数,且(3,b₂)不能通过一步操作到达任何已知P态。
已知P态:(0,0),(1,2)。从(3,b)出发,能到(1,2)的操作有:
- 取第一堆2→(1,b),需b=2 → b=2,但a=3>b=2,不满足a<b
- 取第二堆(b−2)→(3,2),需3=1? no
- 同时取k→(3−k,b−k)=(1,2) → 3−k=1 ⇒ k=2, b−k=2 ⇒ b=4
所以若b=4,则(3,4)可同时取2到(1,2),故(3,4)是N态。下一个b试5:(3,5),能到(1,2)吗?同时取2→(1,3)≠(1,2);取第二堆3→(3,2);取第一堆2→(1,5)。都不行。还需检查是否能到(0,0):同时取3→(0,2)≠(0,0)。所以(3,5)可能是P态。
继续,a₃=4(1,2,3已用),b₃=? 需避开所有能一步到(1,2)或(3,5)的数。到(1,2):同时取k→(4−k,b−k)=(1,2) ⇒ k=3, b=5;到(3,5):同时取k→(4−k,b−k)=(3,5) ⇒ k=1, b=6。所以b不能是5或6。试b=7:(4,7)。检查所有操作目标,若都不在P态中,则加入。
这个过程太繁琐。数学家Wythoff发现:aₖ = ⌊kφ⌋, bₖ = ⌊kφ²⌋,其中φ=(1+√5)/2≈1.618,φ²=φ+1≈2.618。验证k=1:⌊1.618⌋=1, ⌊2.618⌋=2 → (1,2) ✓
k=2:⌊3.236⌋=3, ⌊5.236⌋=5 → (3,5) ✓
k=3:⌊4.854⌋=4, ⌊7.854⌋=7 → (4,7) ✓
k=4:⌊6.472⌋=6, ⌊10.472⌋=10 → (6,10) ✓
为什么是φ?因为φ满足φ²=φ+1,这保证了序列的“无间隙性”:所有正整数恰好出现在{aₖ}或{bₖ}中,且不重复。这是Beatty定理的体现:若α,β>1且1/α+1/β=1,则⌊kα⌋和⌊kβ⌋构成正整数的一个划分。这里α=φ, β=φ²,因为1/φ + 1/φ² = (φ+1)/φ² = φ²/φ² = 1。
所以威佐夫的P态,本质是用黄金分割的无理数特性,在正整数轴上编织一张疏而不漏的网。任何整数对,要么落在网上(P态),要么能一步跳上网(N态)。这张网的经纬度,就是φ的幂。
4.2 实战例题:POJ 1067《取石子游戏》原题解析
题目:两堆石子,数量为a和b。两人轮流操作,每次可:
- 从任意一堆取任意个;
- 从两堆同时取相同个数。
取光者胜。给定a,b,判断先手是否必胜。
这就是威佐夫博奕的标准形态。解法:设a≤b,计算k = b − a,然后检查a是否等于⌊kφ⌋。
但φ是无理数,计算机无法精确存储。怎么办?利用φ的连分数性质:φ = [1;1,1,1,…],其收敛子为斐波那契比:1/1, 2/1, 3/2, 5/3, 8/5, 13/8,… 即Fₙ₊₁/Fₙ。
所以⌊kφ⌋ = ⌊k × Fₙ₊₁ / Fₙ⌋,当Fₙ足够大时,误差小于1。实践中,用double存φ≈1.6180339887498948482,对k≤10⁵,精度足够。
#include <cmath> #include <iostream> using namespace std; int main() { double phi = (1.0 + sqrt(5.0)) / 2.0; int a, b; while (cin >> a >> b) { if (a > b) swap(a, b); int k = b - a; int ak = (int)floor(k * phi); // 注意:floor,不是round if (ak == a) { cout << "0\n"; // 必败 } else { cout << "1\n"; // 必胜 } } }关键细节:
- 必须
floor,因为⌊x⌋是不大于x的最大整数。用round会出错,如k=1, φ≈1.618, floor=1, round=2。 swap(a,b)确保a≤b,因为公式中a是较小值。- 时间复杂度O(1),空间O(1),完美适配POJ时限。
提示:若遇高精度需求(如k达10¹⁸),需用矩阵快速幂计算斐波那契数,再用整除模拟。但99%的竞赛题,double足够。
4.3 黄金分割的实战意义:如何一眼识别威佐夫变种?
很多题不直接说“威佐夫”,但内核相同。识别信号有三:
- 双变量强耦合:操作同时影响两个量,且影响量相等(如“两堆同时减k”、“坐标(x,y)可变为(x−k,y−k)”)。
- 差值恒定性:P态中,b−a=k是常数,而a,b随k增长。
- 无理数比例:当画出所有P态在平面图上,它们近似落在直线y=φx上。
例:Codeforces 1260E《Tournament》简化:n个选手,能力值aᵢ。比赛规则:两人对决,能力高者胜,但若|aᵢ−aⱼ|≤k,则低者可爆冷赢。问最少需多少场,才能让某选手夺冠?
这题的“爆冷”机制,创造了类似威佐夫的“差值阈值”——当能力差≤k时,关系不确定,需额外操作平衡。解法正是将选手按能力分组,组间差>k,组内用威佐夫式配对。
5. 三类博奕的统一视角:状态空间与SG函数
5.1 从特例到一般:什么是SG函数?
巴什、尼姆、威佐夫,看似三个孤立公式,实则是Sprague-Grundy定理在不同状态图上的投影。SG函数是博弈论的“万能接口”。
定义:对任意有向无环图(DAG)上的博弈状态x,其SG值为
sg(x) = mex{ sg(y) | x → y 是一条边 }
其中mex(minimum excludant)是“未在集合中出现的最小非负整数”。
- 终止态(无出边):sg=0
- 若sg(x)=0,则x是P态;否则是N态
为什么?因为sg=0意味着所有后继sg≠0(即全是N态),所以当前玩家必败;sg≠0意味着存在后继sg=0(即存在P态),所以当前玩家可赢。
现在看巴什:状态n,后继是n−1,n−2,…,n−m(若≥0)。sg(0)=0,sg(1)=mex{sg(0)}=mex{0}=1,sg(2)=mex{sg(0),sg(1)}=mex{0,1}=2,…,sg(m)=mex{0,1,…,m−1}=m,sg(m+1)=mex{sg(1),sg(