Jerry's Blog

Back

什么是博弈论#

博弈论,即组合博弈,指一种游戏,这种游戏一般有以下性质:

  1. 两人游戏,且轮流行动
  2. 对等、完全 双方得知信息对等,双方可以进行的行动完全相同.
  3. 确定性 游戏没有随机性的变量(如骰子、随机数等)
  4. 无平局
  5. 有限性 游戏无法无限继续,最终在一定时间内一定有一名玩家胜利,一名玩家失败.

相关定义#

  • 博弈论:研究绝对理性决策者之间战略互动的数学模型.
  • N\color{green}{\mathcal{N}} 必胜态(Next player wins):至少存在一种可能使得对方处于 P\color{red}{\mathcal{P}} 的一种游戏状态被称为必胜态.
  • P\color{red}{\mathcal{P}} 必败态(Previous player wins):存在任意一种方法让对方处于 N\color{green}{\mathcal{N}} 的一种游戏状态被称为必败态.
  • 终局:处于终局时,有且仅有一名玩家获得立即胜利. 如 FPS 游戏中,仅剩 1 名玩家存活就是一个终局.

解决博弈论的一般步骤#

  1. 明确终局
  2. 进行倒推
  3. 寻找规律
  4. 进行数学证明(可以省略)

典例:#

巴什博弈#

考虑总共有 nn 个物品,两名玩家,每次玩家必须至少取 11 个,最多取 mm 个.最后一个物品十分值钱,取到最后一个物品的玩家获胜.

首先,检查这是不是博弈论:

项目结果
两人游戏,且轮流行动符合,是两个人轮流行动
对等、完全符合,每个人只能拿物品,且所有人都知道当前有多少物品
确定性符合,没有随机因素
无平局符合,取到最后一个物品的玩家获胜,不会出现平局
有限性符合,每次玩家必须至少取 1 个,不会出现取不完

所以下定结论,这是博弈论.

明确终局

很显然,终局是场上只剩下一个物品时,此时先手玩家 N\color{green}{\mathcal{N}}

进行倒推

我们尝试推演当 m=2m=2 时的情景,其中,红色节点表示先手玩家 P\color{red}{\mathcal{P}},绿色节点代表先手玩家 N\color{green}{\mathcal{N}}

先选定一个起始节点,起始节点不宜太大,太大则会难于分析,需要选取适中的起始节点.在这里,选择起始节点 n=7n=7

尝试分析起始节点的胜负性.

首先,列举其所有可能的游戏发展子状态.例:n=7n=7 的子状态是 n=6n=6(拿一个) 和 n=5n=5(拿两个)

flowchart LR
7(n=7)--"-1"-->6(n=6)
7--"-2"-->5(n=5)

classDef N fill:#67C23A
classDef P fill:#F56C6C

再列举起始节点所有可能的 游戏发展子状态(这里指 n{5,6}n\in \{5,6\})的游戏发展子状态,一直下去,知道抵达终局(这里指 n=1n=1).

列举完之后如下图:

flowchart LR
7(n=7)--"-1"-->6(n=6)
6--"-1"-->5(n=5)
7--"-2"-->5
6--"-2"-->4(n=4)
5--"-1"-->4
4--"-1"-->3(n=3)
5--"-2"-->3
4--"-2"-->2(n=2)
3--"-1"-->2
2--"-1"-->1(n=1)
3--"-2"-->1

classDef N fill:#67C23A
classDef P fill:#F56C6C

最后,给每一个节点染色.若处于当前状态时先手玩家 P\color{red}{\mathcal{P}} 则将其染成红色,先手玩家 N\color{green}{\mathcal{N}} 则将其染成绿色.

染色规则如下:

  • 终局节点根据游戏规则染色(此题中为 N\color{green}{\mathcal{N}}
  • 若一个节点其所有子节点全为 N\color{green}{\mathcal{N}},则该节点为 P\color{red}{\mathcal{P}},否则该节点为 N\color{green}{\mathcal{N}}

染色完如下:

flowchart LR
7(n=7):::N--"-1"-->6(n=6):::P
6--"-1"-->5(n=5):::N
7--"-2"-->5
6--"-2"-->4(n=4):::N
5--"-1"-->4
4--"-1"-->3(n=3):::P
5--"-2"-->3
4--"-2"-->2(n=2):::N
3--"-1"-->2
2--"-1"-->1(n=1):::N
3--"-2"-->1

classDef N fill:#67C23A
classDef P fill:#F56C6C

列下表:

mn局势
21N\color{green}{\mathcal{N}}
22N\color{green}{\mathcal{N}}
23P\color{red}{\mathcal{P}}
24N\color{green}{\mathcal{N}}
25N\color{green}{\mathcal{N}}
26P\color{red}{\mathcal{P}}
27N\color{green}{\mathcal{N}}

不难发现,当 m=2m=2 时,对于所有的 nn,当且仅当 3n3 \mid nnn 被 3 整除)时先手是 P\color{red}{\mathcal{P}} 的,此外,先手都是 N\color{green}{\mathcal{N}} 的.

数学证明

设整数 kk 满足 k=nmod3k= n \bmod 3,当 k{1,2}k \in \{1,2\} 时,只需要拿取 kk 个,就可以转换为 k=0k=0 的情况,从而先手玩家 P\color{red}{\mathcal{P}}.当 k=0k=0 时,无论拿 1 个还是 2 个,都会转化为 k{1,2}k \in \{1,2\} 的形式,从而先手玩家必败.

推广到 m2m \neq 2 的情况:当 (m+1)n(m+1) \mid n 时,先手是 P\color{red}{\mathcal{P}} 的,此外的所有情况,先手都是 N\color{green}{\mathcal{N}} 的.

Nim 游戏#

P2197 Nim 游戏

甲,乙两个人玩 Nim 取石子游戏.

Nim 游戏的规则是这样的:地上有 n 堆石子,每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取.每次只能从一堆里取.最后没石子可取的人就输了.假如甲是先手,且告诉你这 n 堆石子的数量,他想知道是否存在先手必胜的策略.

显然,这是博弈论.

终局条件是场上没有物品时,此时先手玩家 P\color{red}{\mathcal{P}}

进行倒推

n=1n=1 时,先手玩家只要把这一堆石子取走就可以.故此时,先手玩家 N\color{green}{\mathcal{N}}

n=2n=2 时,为了方便表示,将 x_y 表示为第一堆剩下 x 个,第二堆剩下 y 个的情况.xyx\geq y

显然,当有一堆时 0 时,先手玩家可以直接拿走那一堆,故此时,先手玩家 N\color{green}{\mathcal{N}}

选取 3,2 为初始节点,列表:

flowchart TD
    classDef N fill:#67C23A
    classDef P fill:#F56C6C

    %% 节点声明(顺序也会影响布局)
    0_0:::P
    1_0:::N
    1_1:::P
    2_0:::N
    2_1:::N
    2_2:::P
    3_0:::N
    3_1:::N
    3_2:::N

    %% 从小局势开始连接,逐步到大局势
    %% (1,1) 出发
    1_1--"-1"-->1_0

    %% (2,1) 出发
    2_1--"-1"-->1_1
    2_1--"-2"-->1_0
    2_1--"-1"-->2_0

    %% (2,2) 出发
    2_2--"-1"-->2_1
    2_2--"-2"-->2_0

    %% (3,1) 出发
    3_1--"-1"-->2_1
    3_1--"-1"-->3_0
    3_1--"-2"-->1_1
    3_1--"-3"-->1_0

    %% (3,2) 出发
    3_2--"-1"-->2_2
    3_2--"-1"-->3_1
    3_2--"-2"-->2_1
    3_2--"-2"-->3_0
    3_2--"-3"-->2_0

好像当且仅当 x=yx=y 时为 P\color{red}{\mathcal{P}},其他时候都是 N\color{green}{\mathcal{N}}

证明也很简单,所有非 x=yx=y 的状态都可以一步转化为 x=yx=y 这个 P\color{red}{\mathcal{P}} 的状态.

那么,如何推广呢?

Nim 和#

定义一组数 a1,a2,a3,,ana_1,a_2,a_3,\cdots, a_nNim 和a1a2ana_1\oplus a_2\oplus\cdots\oplus a_n

异或运算 \oplus

异或是一种逻辑运算符,其法则为相同为 0,不同为 1,异或可以视为不进位加法运算.

其真值表如下:

AABBABA\oplus B
000
011
101
110

对于两个数之间的异或运算,需要将它们转化为二进制之后对每一位进行异或.

计算:535\oplus 3

53=(101)2(11)2=(110)2=6\begin{aligned} 5\oplus 3 &=(101)_2 \oplus (11)_2\\ &=(110)_2\\ &=6\\ \end{aligned}

除了交换律、结合律外,异或还拥有一些性质:

  • 异或具有自反性:kaa=kk\oplus a \oplus a = k
  • 异或拥有恒等律:k0=kk\oplus 0 = k

那么,当一个状态满足其 Nim 和为 0 是,当前状态为 P\color{red}{\mathcal{P}}

证明

把每堆石子数写成二进制(比如 3 写成 11,5 写成 101),然后靠右对齐每一位,数一下这一位上一共有几个 1.

如果每一位上 1 的个数都是偶数,定义这个状态为“平衡”(Nim 和为 0).如果至少有一位上 1 的个数是奇数,定义这个状态为“不平衡”(Nim 和不为 0).

举个例子:两堆,3 和 5

  • 3 → 011
  • 5 → 101

对齐(假设三位):

  • 第 0 位(最右):3 有 1,5 有 1 → 共 2 个 1(偶数)
  • 第 1 位:3 有 1,5 有 0 → 共 1 个 1(奇数)
  • 第 2 位:3 有 0,5 有 1 → 共 1 个 1(奇数)

所以不平衡(Nim 和不为 0).

如果两堆都是 3:

  • 3 → 011
  • 3 → 011

每位 1 的个数:

  • 第 0 位 2 个(偶)
  • 第 1 位 2 个(偶)
  • 第 2 位 0 个(偶)→ 平衡(Nim 和为 0).

对于这个平衡状态,有两条性质:

性质 1:从平衡状态出发,无论你如何操作,只要操作是合法的,一定会变成不平衡状态.

为什么?因为你想保持平衡,就得让每一堆的每一二进制位上的 1 的个数都还是偶数.但当你只改一堆时,那堆的某些位从 1 变 0 或 0 变 1,必然导致至少一位上 1 的个数从偶数变成奇数.所以平衡 → 不平衡是必然的.

性质 2:从不平衡状态出发,总有一种拿法,让它变回平衡状态.

怎么找?找出二进制中“最高那位出现奇数个 1 的位”(如在两堆分别是 3 和 5 时,是右起第三位),然后选一堆在那一位上是 1 的,从这堆里拿走恰好能让所有位都变偶数的石子数.这个操作一定可行(因为那堆原来的石子数足够多).所以不平衡 → 平衡是可以做到的.

终局时所有堆都是 0,写出来全是 0,每一位上 1 的个数都是 0(偶数),所以终局是平衡状态

而且谁面对终局谁就输了(因为没石子可拿).

因此,假设开局是平衡状态(Nim 和为 0).先手只能把它变成不平衡(性质 1).后手面对不平衡,可以把它变回平衡(性质 2).如此循环:平衡→不平衡→平衡→不平衡……因为终局是平衡状态,所以最后一定是后手把局面变成终局(平衡),然后轮到先手时无石子可拿,先手输.

如果开局是不平衡状态,先手第一步就可以把它变成平衡,然后自己扮演上面“后手”的角色,最终让对手面对终局,所以先手赢.

由以上证明可以推导出博弈论证明的基本方法:

  1. 明确一个必输终局有的性质,记之为 RR.
  2. 对于 RR,如果所有操作都能破环性质 RR,且所有不符合性质 RR 的局面都至少有 1 种操作能使局面具有 RR 性质.那么 RR 就是所有必输局面的共同性质.

阶梯 Nim#

题目简介

共有 nn 堆石子,第 ii 堆有 aia_i 枚石子.两名玩家轮流操作,每次操作中,要么取走第 1 堆石子中的任意多枚,要么将第 i>1i > 1 堆石子中的任意多枚移动到第 i1i-1 堆,但不能不做任何操作.取走最后一枚石子的玩家取胜.

在问题中,处于偶数堆的石子可以视为不存在,因为当先手将偶数堆的石子向下移移到奇数堆,后手可以再将这些石子再向下又移到偶数堆.直到从第 1 堆拿走.

因此,影响战局的只会是奇数堆.再次观察,每一次移动奇数堆的石子,都会使其移动到偶数堆上,又因为偶数堆上的石子可以视为没有,所以,每一次移动奇数堆上棋子到偶数堆,等同于将这些石子移出游戏.这样,阶梯 Nim 游戏就相当于以每一个奇数堆为一个有效堆的 Nim 游戏.

SG 函数#

定义一个局面 xxSG 值sg(x)sg(x),则有

sg(x)=mex{sg(ai)aix}sg(x) = mex\{sg(a_i) \mid a_i \rightarrow x\}

,其中,aixa_i\rightarrow x 的意思是能从局面 aia_i 通过一次合法的操作转换为 xx

mex

mex 指在一个序列中,最小的、不在这个序列中的自然数.

因此,不难得出,当 sg(x)=0sg(x) = 0,则局面 xx 先手必败,否则先手必胜.

举个例子,就拿巴氏博弈(m=2m=2)来说,可列下表:

xxaia_isg(ai)sg(a_i)sg(x)sg(x)先手局势
0\varnothing\varnothing0P\color{red}{\mathcal{P}}
1{0}\{0\}{0}\{0\}1N\color{green}{\mathcal{N}}
2{0,1}\{0,1\}{0,1}\{0,1\}2N\color{green}{\mathcal{N}}
3{1,2}\{1,2\}{1,2}\{1,2\}0P\color{red}{\mathcal{P}}
4{2,3}\{2,3\}{2,0}\{2,0\}1N\color{green}{\mathcal{N}}
5{3,4}\{3,4\}{0,1}\{0,1\}2N\color{green}{\mathcal{N}}
6{4,5}\{4,5\}{1,2}\{1,2\}0P\color{red}{\mathcal{P}}

对于多个相对独立的游戏同时进行(例如:考虑总共 nn 堆物品,每堆有 aia_i 个物品,两名玩家,每次玩家必须至少取 11 个,最多取 mm 个,且不能跨堆取.最终,无法操作的玩家落败.这是多个巴士博弈的游戏同时进行.),则总游戏的 SG 值与其分游戏的 SG 值有如下关系:

sg(a1,a2,,an)=sg(a1)sg(a2)sg(an)sg(a_1, a_2, \cdots, a_n) = sg(a_1) \oplus sg(a_2) \oplus \cdots \oplus sg(a_n)

Nim 游戏就是一个典型的多个相对独立的游戏同时进行的游戏,以下是每个独立游戏,即为单堆石子可列表格:

xxaia_isg(ai)sg(a_i)sg(x)sg(x)先手局势
0\varnothing\varnothing0P\color{red}{\mathcal{P}}
1{0}\{0\}{0}\{0\}1N\color{green}{\mathcal{N}}
2{0,1}\{0,1\}{0,1}\{0,1\}2N\color{green}{\mathcal{N}}
3{0,1,2}\{0,1,2\}{0,1,2}\{0,1,2\}3N\color{green}{\mathcal{N}}
4{0,1,2,3}\{0,1,2,3\}{0,1,2,3}\{0,1,2,3\}4N\color{green}{\mathcal{N}}
5{0,1,2,3,4}\{0,1,2,3,4\}{0,1,2,3,4}\{0,1,2,3,4\}5N\color{green}{\mathcal{N}}
nn>0n\mid n > 0{0,1,,n1}\{0,1,\cdots,n-1\}{0,1,,n1}\{0,1,\cdots,n-1\}nnN\color{green}{\mathcal{N}}

因此,对于一个具有 nn 堆石子,第 ii 堆有 aia_i 个的 Nim 游戏,整体游戏的 SG 值如下:

sg(ai1in)=a1a2ansg(a_i\mid 1\leq i\leq n) = a_1 \oplus a_2\oplus\cdots\oplus a_n

不难发现,Nim 游戏的 SG 值就等于其 Nim 和,则从侧面证明了 Nim 游戏策略的正确性.

解决博弈论问题的一般策略#

了解了 SG 函数,接下来就可以总结博弈论问题的一般策略.

  1. 理解题意,提炼出博弈论模型.
  2. 根据规则,手推或者计算机打表求出一些小数据的 SG 值.
  3. 寻找规律.
  4. 根据规律编程解决问题.
P4018 Roy&October 之取石子

题目描述#

Roy 和 October 两人在玩一个取石子的游戏.共有 nn 个石子,两人每次都只能取 pkp^k 个( pp 为质数,kk 为自然数,且 pkp^k 小于等于当前剩余石子数),谁取走最后一个石子,谁就赢了.

现在 October 先取,问她有没有必胜策略.

若她有必胜策略,输出一行 October wins!;否则输出一行 Roy wins!

输入格式#

第一行一个正整数 TT,表示测试点组数.

22\simT+1T+1 行,一行一个正整数 nn,表示石子个数.

输出格式#

TT 行,每行分别为 October wins!Roy wins!

数据范围#

对于 100%100\% 的数据,1n5×1071\leq n\leq 5\times 10^7, 1T1051\leq T\leq 10^5

博弈论模型不难提炼.根据规则,可以写出如下的打表程序:

在这里,由于只有 1 个独立游戏,因此,我们只关心 SG 值是否为 0.在这里,我打印出了所有 SG 值为 0 的情况.

输出如下:

6 12 18 24 30 36 42 48 54 60 66 72 78 84 90 96
plaintext

不难发现,某一局面的 SG 值为 0 当且仅当 nn 是 6 的倍数.

因此,可以编写程序:

博弈论
https://blog.jerrylab.top/blog/count/game-theory
Author Jerry
Published at 2026年3月29日