博弈论算法常见模型整理

这篇具有很好参考价值的文章主要介绍了博弈论算法常见模型整理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

博弈论

一、内容简介

本文主要介绍算法竞赛中常常出现的博弈论模型,包括:

  1. 4个经典组合游戏
  2. SG函数
  3. SG游戏及拓展

二、前置概念

进一步学习需要了解一些前置概念

  1. ICG
  2. 博弈图
  3. P点、N点
  4. mex函数

1.ICG

ICG全称为“公平组合游戏”,我们下面讨论的博弈游戏均建立在ICG的基础上,那么什么是ICG呢,它需要满足以下条件:

  • 由两名玩家交替行动
  • 对任意局面,接下来可执行的行动仅与局面有关(玩家平等)
  • 游戏以玩家无法行动为结束,且无平局

那么称此游戏为“公平组合游戏

2.博弈图

我们可以看到,整个过程是各个状态的集合,且状态间可以到达,那么我们可以将这个博弈过程抽象为一张图,称为博弈图,这个游戏我们也称之为有向图游戏

那么这个图是一个有向无环图,图中有唯一的起点,可能有多个终点,两名玩家的交替行动可认为是图上的有向边,所有出度为0的节点便是终点

对于这个图,每个节点存储如下信息:{弈盘信息x,先手信息p,…}等

同时有如下结论:任何一个公平组合游戏均可以转化为有向图游戏

3.P点、N点

P点和N点是博弈里面两个及其重要的概念

  • 先手必胜状态:先手行动后,可以将一个必败状态留给后手
  • 先手必败状态:先手无论如何行动,只能将必胜状态留给后手
  • 必败点(P点):前一个选手取胜,当前选手将败的节点(previous)
  • 必胜点(N点):下一个选手将败,当前选手取胜的节点(next)

4.mex函数

mex函数是一个建立在集合上的整数函数,即 m e x : S N ↦ N mex: S_N \mapsto N mex:SNN ,它的定义域是一个非负整数集, m e x mex mex代表这个集合里最小未出现的非负整数,举几个例子: m e x ( { 1 , 2 , 3 } ) = 0 mex(\{1,2,3\})=0 mex({1,2,3})=0 m e x ( { 0 , 1 , 2 } ) = 3 mex(\{0,1,2\})=3 mex({0,1,2})=3 m e x ( { 0 , 2 , 3 } ) = 1 mex(\{0,2,3\})=1 mex({0,2,3})=1,等等

三、前置定理

定理一:没有后继状态的状态是必败状态

定理二:一个状态是必胜状态 ⇔ \Harr 它至少存在一个向必败状态的转移

定理三:一个状态是必败状态 ⇔ \Harr 它所有后继状态均为必胜状态

四、四大经典组合游戏

1.Nim游戏

给定 N N N 堆物品,第 i i i堆物品有 A i A_i Ai 个。

两名玩家轮流行动,每次可以任选一堆,取走任意多个物品,可把一堆取光,但不能不取。

取走最后一件物品者获胜。

问先手是否必胜。

Nim博弈是最经典的博弈之一,许多博弈均可转化为Nim博弈,我们给出结论:

先手必胜 ⇔ \Harr A 1 ⊕ A 2 ⊕ A 3 . . . ⊕ A n ≠ 0 A_1\oplus A_2\oplus A_3...\oplus A_n\ne0 A1A2A3...An=0

由归纳法其实很容易证得,也可以利用三个前置定理进行证明,但这个等价表达式还是给予我们很多震撼~~(也给予出题人很多灵感)~~

但其实我们不应把Nim游戏看成一个独立游戏,而应该把它看成若干个游戏的和

对每个游戏,先手是否必胜 ⇔ \Harr A i ≠ 0 A_i\ne0 Ai=0

进而对于这 n n n 个游戏的加和为 A 1 ⊕ A 2 ⊕ A 3 . . . ⊕ A n A_1\oplus A_2\oplus A_3...\oplus A_n A1A2A3...An

游戏和的概念后续还会继续用到,也是用异或的形式给出表达式,这个表达式很重要

int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; ++ i)  scanf("%d", &x), ans ^= x;
    puts("%s", ans ? "Yes" : "No");
    return 0;
}

2.Bash游戏

有 1 堆石子,总个数是 n n n

两名玩家轮流在石子堆中拿石子,每次至少取 1 个,至多取 m m m 个。

取走最后一个石子的玩家为胜者。

判定先手和后手谁胜。

给出结论:

先手必胜 ⇔ \Harr ( m + 1 ) ∤ n (m+1)\nmid n (m+1)n

考虑三种情形 :

情形一: n ≤ m n \le m nm时,显然先手必胜

情形二: n = m + 1 n=m+1 n=m+1时,先手最多拿m个,但无论先手取走几个,后手一定可以拿完,后手胜

情形三: ( m + 1 ) ∣ n (m+1)\mid n (m+1)n 时,假设先手每次拿 x x x 个,后手可以拿 m + 1 − x m+1-x m+1x 个,最后后手胜

其余情形,先手均可以通过拿走 n % ( m + 1 ) n \% (m+1) n%(m+1) 个,进而转至情形三,先手胜

int main() {
	scanf("%d%d", &n, &m);
    puts("%s", n%(m+1) ? "First Win" : "Second Win");
    return 0;
}

3.Wythoff游戏

有两堆石子,石子数可以不同。

两人轮流取石子,每次可以在一堆中取,或者从两堆中取走相同个数的石子,数量不限.

取走最后一个石头的人获胜。

判定先手是否必胜。

这个游戏的结论比较复杂,涉及到了平面上的点集,下图便是先手必败节点, ( x , y ) (x,y) (x,y) 代表两堆石子个数

img

上面这张图粉色区域即为解集,解集是关于 y = x y=x y=x 对称,靠前的解有: ( 0 , 0 ) , ( 1 , 2 ) , ( 3 , 5 ) , ( 4 , 7 ) , ( 6 , 10 ) , ( 8 , 13 ) , ( 9 , 15 ) , ( 11 , 18 ) , ( 12 , 20 ) , ( 13 , 21 ) . . . (0,0), (1,2), (3,5), (4,7), (6,10), (8,13), (9,15), (11,18), (12,20), (13,21)... (0,0),(1,2),(3,5),(4,7),(6,10),(8,13),(9,15),(11,18),(12,20),(13,21)...

解集 ( a k , b k ) (a_k,b_k) (ak,bk) 满足 : a k a_k ak 是之前未出现的最小自然数, b k = a k + k b_k=a_k+k bk=ak+k

这个可以利用题目的性质进行归纳证明,主要利用了如下性质:

  • ( x , y ) ∈ A n s (x,y) \in Ans (x,y)Ans ,那么 ∀ t ∈ N , ( x + t , y ) ∉ A n s , ( x , y + t ) ∉ A n s , ( x + t , y + t ) ∉ A n s \forall t\in \N,(x+t,y)\notin Ans ,(x,y+t)\notin Ans,(x+t,y+t)\notin Ans tN,(x+t,y)/Ans,(x,y+t)/Ans,(x+t,y+t)/Ans

我们称符合要求的解为奇异节点,奇异节点便是先手必败节点,而非奇异节点显然可以通过一步操作变成奇异节点,通过归纳法也可以证明奇异节点坐标正确性

按照解的定义,我们发现实际上集合 A = { a k ∣ k ∈ N } A=\{a_k|k\in \N\} A={akkN} B = { b k ∣ k ∈ N } B=\{b_k|k\in \N\} B={bkkN} 实际上是对整数区间的一个划分,即 A ∩ B = ∅ , A ∪ B = N + A\cap B=\varnothing,A\cup B=\N^+ AB=,AB=N+ ,考虑引入Beatty定理

如果两个无理数 α , β \alpha,\beta α,β 满足:

1 α + 1 β = 1 \frac{1}{\alpha}+\frac{1}{\beta}=1 α1+β1=1

考虑两个正整数集 A , B A,B A,B

A = { ⌊ n α ⌋ } , B = { ⌊ n β ⌋ } A=\{\lfloor n\alpha \rfloor\},B=\{\lfloor n\beta \rfloor\} A={nα},B={nβ} ( 1 ) (1) (1)

以及两个结论:

A ∩ B = ∅ , A ∪ B = N + A\cap B=\varnothing,A\cup B=\N^+ AB=,AB=N+ ( 2 ) (2) (2)

那么我们断言: ( 1 ) ⇔ ( 2 ) (1)\Harr(2) (1)(2) ,可利用取整函数的上下界进行证明

Beatty定理 代入我们的解集,利用 β = α + 1 \beta = \alpha +1 β=α+1 解出: α = 5 + 1 2 , β = 3 − 5 2 \alpha = \frac{\sqrt{5}+1}{2} ,\beta=\frac{3-\sqrt{5}}{2} α=25 +1,β=235

假设两堆石子为 ( a k , b k ) , a k < b k (a_k,b_k),a_k \lt b_k (ak,bk),ak<bk ,那么先手必败 ⇔ \Harr ( b k − a k ) × α = k α = a k (b_k-a_k)\times \alpha =k \alpha = a_k (bkak)×α=kα=ak

int main() {
	scanf("%d%d", &n, &m);
    if (a > b) swap(a, b);
    int ans = (b - a) * ((1.0 + sqrt(5.0)) / 2.0);
    puts("%s", ans==a ? "Second Success" : "First Success");
    return 0;
}

4.Fibonacci游戏

有 1 堆石子,总个数是 n n n ( n ≥ 2 ) (n\ge 2) (n2)

游戏双方轮流取石子,规则如下:

先手不能在第一次把所有的石子取完,至少取 1 颗;

之后每次可以取的石子数至少为 1 ,至多为对手刚取的石子数的 2 倍。

取走最后一个石子的人为赢家,求必败态。

结论:

先手必败 ⇔ \Harr 石子数为斐波那契数

必要性可由归纳法简要证出,充分性建立在 Zeckendorf定理

任何正整数均可以表示为若干个不连续的 Fibonacci 数之和

进而先手可以将石子划分成多堆不连续的斐波那契数的加和,先手先取走最小堆,然后可以通过操作,让后手来面临这些斐波那契堆,且每次后手不能取完,而先手可以取完,最后先手取完最后的石子,先手胜

int f[N], x;
map<int,bool>mp;
int main(){
	fib[1] = 1,	fib[2] = 1;
	for(int i = 3;i <= 50; ++ i) f[i] = f[i-1] + f[i-2], mp[f[i]] = 1;
	while(scanf("%d", &x) && x != 0)
		puts(mp[x] == 1 ? "Second win" : "First win");
    return 0;
}

五、SG函数

1.SG函数

SG函数是对博弈图中每一个节点或者说状态的评估函数, S G : s t a t e ↦ N SG: state \mapsto N SG:stateN

规定游戏终点的 SG 函数值为 0 ,即 S G ( e n d ) = 0 SG(end)=0 SG(end)=0 ,同时扩展规定一个游戏图的 SG 值为起点的 SG 值,即 S G ( G r a p h ) = S G ( s t a r t ) SG(Graph)=SG(start) SG(Graph)=SG(start)

在有向图游戏中,对每个节点 x x x

设从 x x x 出发有 k k k 个状态转移,分别到达节点 y 1 , y 2 , . . . , y k y_1,y_2,...,y_k y1,y2,...,yk

那么定义 S G ( x ) SG(x) SG(x) x x x 的后继节点的 S G SG SG 值集合取 m e x mex mex

即: S G ( x ) = m e x ( { S G ( y 1 ) , S G ( y 2 ) , . . . , S G ( y k ) } ) SG(x) = mex(\{SG(y_1),SG(y_2),...,SG(y_k)\}) SG(x)=mex({SG(y1),SG(y2),...,SG(yk)})

博弈论算法常见模型整理

那么由前置定理,推出以下结论:

  • S G ( x ) = 0 SG(x)=0 SG(x)=0 ,则为必败状态
  • S G ( x ) ≠ 0 SG(x)\not=0 SG(x)=0 ,则为必胜状态

2.SG定理

SG 定理 :

对于游戏 X X X ,它可以拆分成若干个子游戏 x 1 , x 2 , . . . , x n x_1,x_2,...,x_n x1,x2,...,xn X = ⋃ i = 1 n x i X = \bigcup_{i=1}^{n}x_i X=i=1nxi

那么, S G ( X ) = ⊕ i = 1 n S G ( x i ) = S G ( x 1 ) ⊕ S G ( x 2 ) ⊕ . . . ⊕ S G ( x n ) SG(X)=\oplus_{i=1}^{n}SG(x_i)=SG(x_1)\oplus SG(x_2)\oplus...\oplus SG(x_n) SG(X)=i=1nSG(xi)=SG(x1)SG(x2)...SG(xn)

换句话说,对于由 n n n 个有向图组成的组合游戏,设它们的起点为 s 1 , s 2 , . . . , s n s_1,s_2,...,s_n s1,s2,...,sn 当且仅当 S G ( s 1 ) ⊕ S G ( s 2 ) ⊕ . . . ⊕ S G ( s n ) ≠ 0 SG(s_1)\oplus SG(s_2)\oplus...\oplus SG(s_n) \not=0 SG(s1)SG(s2)...SG(sn)=0 时,这个游戏为先手必胜

证明方法与 Nim 游戏的证明类似

事实上,每一个简单 SG-组合游戏 都可以完全等效成一堆数目为 K K K 的石子,其中 K K K 为该简单游戏的 SG函数值。

定义游戏的和

考虑任意多个同时进行的 SG-组合游戏,这些 SG-组合游戏的和 是这样一个SG-组合游戏:

在它进行的过程中,游戏者可以任意挑选其中的一个 单一游戏 进行决策,

最终,没有办法进行决策的人输。

易见,SG定理是对 游戏的和的SG值 和 单一游戏的SG值 间关系的一座桥梁,揭示了两者间的关系

3.简单应用

博弈论算法常见模型整理
#include <unordered_set>  // AcWing 893
int n, m, x, res;
int a[N], s[N], ans[M];
int sg(int x){//记忆化搜索
    if(ans[x] != -1) return ans[x];
    unordered_set<int>St;
    for(int i = 1; i <= m; i++) if(x >= s[i]) St.insert(sg(x - s[i]));
    for(int i = 0; ; i++)  if(!St.count(i)) return ans[x] = i; // 求 mex
}
int main(){
    scanf("%d", &m);
    for(int i = 1; i <= m; i++)  scanf("%d", &s[i]);// m 个起点
    scanf("%d", &n);
    memset(ans, -1, sizeof ans);
    for(int i = 1; i <= n; i++) scanf("%d", &x), res ^= sg(x);
    puts("%s", res ? "Yes" : "No");
    return 0;
}

六、SG游戏及拓展

这一章节我们讲述 SG 游戏以及一些常见的扩展和应用,包括以下内容:

  1. A n t i − S G Anti-SG AntiSG 游戏
  2. M u l t i − S G Multi-SG MultiSG 游戏
  3. E v e r y − S G Every-SG EverySG 游戏
  4. 翻硬币游戏
  5. 无向图删边游戏

1. A n t i − S G Anti-SG AntiSG 游戏

n n n 堆石子

两个人可以从任意一堆石子中拿任意多个石子,不能不拿,

拿走最后一个石子的人失败

求必胜策略

这个似乎与 S G SG SG 定理是相反的, S G SG SG 函数建立在可执行决策上,它认为当可执行决策为空时(终点态) S G SG SG 为 0 ,但这个游戏无法通过可执行决策来确切判断胜负,那我们是否要建立新的 S G SG SG 定理了呢

先给出结论:先手必胜等价于

  • ∀ i , A i ≤ 1   &   S G ( X ) = 0 \forall i,A_i \le 1 \space \& \space SG(X)=0 i,Ai1 & SG(X)=0
  • ∃ i , A i > 1   &   S G ( X ) ≠ 0 \exist i,A_i \gt 1 \space \& \space SG(X)\not=0 i,Ai>1 & SG(X)=0

简证:第一点显然,对于第二点,若 S G ( X ) ≠ 0 SG(X)\not=0 SG(X)=0 ,先手每次操作使得其为 0 ,一直下去,使得最终只有一堆的石子数大于 1 ,此时,轮到先手操作,先手可以让局面变成只有奇数个 1 ,先手胜

其实除了全为 1 的情况,剩下情况还是符合常规 S G SG SG 定理的,我们分析一下 A n t i − N i m Anti-Nim AntiNim 与常规 N i m Nim Nim 的区别,主要区别在于 S G ( X ) = 0 SG(X)=0 SG(X)=0 时,我们无法判负,为解决这个几乎与常规 N i m Nim Nim 颠倒的博弈,我们引出下面的 S J SJ SJ 定理

首先给出 A n t i − S G Anti-SG AntiSG 游戏的具体定义:

决策集合为空的游戏者获胜,生成终止局面的游戏者判负

其余规则与普通的 S G SG SG 游戏相同。

再给出 S J SJ SJ 定理:

对于任意一个 A n t i − S G Anti-SG AntiSG 游戏

如果我们规定当局面中所有的单一游戏(不可再分割游戏)的 S G SG SG 值为 0 时,游戏结束

那么先手必胜等价于:

(1) ∀ i , S G ( x i ) ≤ 1   &   S G ( X ) = 0 \forall i,SG(x_i)\le 1\space \& \space SG(X)=0 i,SG(xi)1 & SG(X)=0

(2) ∃ i , S G ( x i ) > 1   &   S G ( X ) ≠ 0 \exist i,SG(x_i)\gt 1\space \& \space SG(X)\not=0 i,SG(xi)>1 & SG(X)=0

证明与上述 A n t i − N i m Anti-Nim AntiNim 类似

// Luogu P4279 Anti-Nim 模板题
int n, m, t, k;
int a[N];
int main(){
    scanf("%d", &t);
    while(t -- ) {
        scanf("%d", &n);
        int sg = 0, flag = 0;
        for(int i = 1; i <= n; ++ i) {
            scanf("%d", &a[i]), sg ^= a[i];
            if(a[i] > 1) flag = 1;
        }
        if((flag == 0 && sg == 0) || (flag == 1 && sg != 0))  puts("John");
        else puts("Brother");
    }
    return 0;
}

2. M u l t i − S G Multi-SG MultiSG 游戏

n n n 堆石子

两个人可以从任意一堆石子中拿任意多个石子,不能不拿

或者可以把一堆数量不少于 2 2 2 石子堆分为两堆不为空的石子堆

无法操作的人失败

问谁有必胜策略

给出结论:

S G ( x ) = { x − 1 , x ≡ 0 ( m o d 4 ) x , x ≡ 1 & 2 ( m o d 4 ) x + 1 , x ≡ 3 ( m o d 4 ) SG(x)=\begin{cases} x-1 ,& x \equiv 0 \pmod 4 \\ x, & x \equiv 1 \&2 \pmod 4 \\ x+1, &x\equiv 3 \pmod 4 \end{cases} SG(x)=x1,x,x+1,x0(mod4)x1&2(mod4)x3(mod4)

S G ( X ) = ⊕ i = 1 n S G ( x i ) SG(X)=\oplus_{i=1}^n SG(x_i) SG(X)=i=1nSG(xi)

具体怎么来的,是依靠 独特的智慧 打表 来的,不过事实上,打表也确实是很重要 博弈类游戏 结论发现来源,不是所有人都有着拉马努金那种高超的直觉和经验

我们再来给出 M u l t i − S G Multi-SG MultiSG 的准确定义:

M u l t i − S G Multi-SG MultiSG 游戏规定,在符合拓扑原则的前提下,一个单一游戏的后继可以为 多个单一游戏 。

M u l t i − S G Multi-SG MultiSG 其他规则与 S G SG SG 游戏相同。

那么它有如下性质:

  • 一个后继状态的SG值 为 后继状态中所能衍生出的所有独立游戏的异或和

举个简单的例子: S G ( 3 ) SG(3) SG(3) 的后继状态有 { ( 0 ) , ( 1 ) , ( 2 ) , ( 1 , 2 ) } \{(0),(1),(2),(1,2)\} {(0),(1),(2),(1,2)} 也就是这堆有 3 3 3 个石子的石子堆,可以拿走或者分开等四种情况,他们的 S G SG SG 值分别为 $ { 0 , m e x { 0 } = 1 , m e x { 0 , 1 } = 2 , m e x { 0 , 1 , 2 } = 3 }$,因此 $SG(3)=mex{0,1,2,3}=4 $

int n, a[N], sg[N]; // hdu 3032 Multi-Nim 模板
int main(){
    int t, scanf("%d", &t);
    while(t -- ) {
        int ans = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
        for(int i = 1; i <= n; ++ i) {
            if(a[i] % 4 == 0) sg[i] = a[i] - 1;
            else if(a[i] % 4 == 3) sg[i] = a[i] + 1;
            else sg[i] = a[i];
            ans ^= sg[i];
        }
        puts("%s", ans ? "Alice" : "Bob")
    }
    return 0;
}
int sg[M], vis[M]; // hdu 3032 打表代码
int main(){ // 对于一堆石子,数量为 M ,打表出 SG[M]
    sg[0] = 0, sg[1] = 1;
    for (int i = 2; i < M; ++ i){
        memset(vis, 0, sizeof(vis));
        //操作一,至少取一个
        for (int j = 1; j <= i; ++ j) vis[sg[i - j]] = 1;
        //操作二,分成两堆,不为空
        for (int j = 1; j < i; ++ j) vis[sg[j] ^ sg[i - j]] = 1;
        int j = 0; while (vis[j]) j ++ ;
        sg[i] = j;
    }
    for (int i = 1; i <= M; ++ i) printf("sg[%d] : %d\n", i, sg[i]);
    return 0;
}

3. E v e r y − S G Every-SG EverySG 游戏

给定一张无向图,上面有一些“棋子”

每人每次必须将所有可以移动的棋子都进行移动

最后不能移动的人输

求是否有必胜策略

还有一道 杭电OJ (HDU-3595) 的题:

GG和MM喜欢玩游戏。在游戏开始时,有两堆石头。

MM首先选择一堆石头,里面有 x x x 块石头,然后选择一个正数k,从另一堆有 y y y 块石头的堆中取走 k x kx kx 块石头 ( y ≥ k x ) (y\ge kx) (ykx)

然后是轮到了GG,也遵循上述规则选择石头。

当有人不能移除任何石头时,他就输掉了比赛,这个游戏就结束了。

很多年后,GG和MM发现这个游戏太简单了,所以他们决定一次同时玩 N N N 个上述游戏。

MM先手,当进入他的回合时,他必须对每个未完成的游戏进行操作。

取石头规则与上述相同,如果有人无法取走任何石头(即输掉最后一场结束游戏),那么他就输了

对于每个测试用例,输出获胜者的姓名

给出 E v e r y − S G Every-SG EverySG 游戏的具体定义:

E v e r y − S G Every-SG EverySG 游戏规定,对于还没有结束的单一游戏,玩家必须对该游戏进行一步决策

E v e r y − S G Every-SG EverySG 游戏的其他规则与普通 S G SG SG 游戏相同

E v e r y − S G Every-SG EverySG 游戏与普通 S G SG SG 游戏最大的不同就是它多了一维:时间

对于 S G SG SG 值为0的点,我们需要知道最少需要多少步才能走到结束,

对于 S G SG SG 值不为0的点,我们需要知道最多需要多少步结束

所有游戏都是独立的,并且我们发现无法操作者输,而同时又在进行多个游戏。因此,我们知道胜负情况最终由最后结束的游戏的胜负情况觉定。

既然只与最后结束的游戏相关,那么我们便不会太在意除最后一个游戏外其他游戏的胜负。

而且又由于我们得同时操作所有柚子,所以,对于我们必胜的游戏,我们一定会想办法将其尽可能的向后拖,尽可能完的结束;反过来,对于我们必败的游戏,我们一定会让他尽可能早的结束。

那么,我们首先可以判定出所有位置是 N N N 点还是 P P P 点,然后按照判定决策我们按拖延方案走还是加速方案走。

这样我们用 s t e p step step 变量来记录每个单一游戏的这个步数,有点像关键路径算法

s t e p ( u ) = { 0 , u ∈ E n d max ⁡ { s t e p ( v ) } + 1 , < u , v > ∈ E , u ∈ N , v ∈ P min ⁡ { s t e p ( v ) } + 1 , < u , v > ∈ E , u ∈ P step(u)=\begin{cases} 0 ,& u \in End \\ \max \{step(v)\}+1, & <u,v>\in E,u\in N,v\in P \\ \min\{step(v)\}+1, &<u,v>\in E,u\in P \end{cases} step(u)=0,max{step(v)}+1,min{step(v)}+1,uEnd<u,v>E,uN,vP<u,v>E,uP

给出必胜结论:

对于 E v e r y − S G Every-SG EverySG 游戏,

先手必胜 ⇔ \Harr 单一游戏中最大的 s t e p step step 为奇数

结论建立在以下三条性质上,可以归纳地证明,或者显然地感觉出它们是对的:

  • 对于所有的单一游戏,先手必胜状态的 s t e p step step 值为奇数,先手必败状态的 s t e p step step 值为偶数
  • 设最大的 s t e p step step m a x s max_s maxs ,那么胜手可以保证该单一游戏最少会在 m a x s max_s maxs 步结束
  • 设最大的 s t e p step step m a x s max_s maxs ,那么胜手可以保证他所有必败的游戏最多在 m a x s max_s maxs 步结束

然后下面解决 HDU-3595 的题目,不过最好先看下 HDU-1525

浅要说下 HDU-3595 中单一游戏 N / P N/P N/P 判定的结论,这个单一游戏的背景来源于 E u c l i d Euclid Euclid 游戏

假设 a ≥ b a\ge b ab,那么如果 a = b a=b a=b,先手必胜,如果 a % b = 0 a\%b=0 a%b=0 ,先手必胜,

而如果 b < a < 2 b b<a<2b b<a<2b 的话,怎么取就已经定了,

进而如果 a > 2 ∗ b a>2*b a>2b ,那么先手可以决定谁先取到 b < a < 2 b b<a<2b b<a<2b 这个状态,

所以当 a > 2 ∗ b a>2*b a>2b 时,先手必胜,只用讨论当 b < a < 2 b b<a<2b b<a<2b 时最后谁胜

int n,m,sg[MAX][MAX],step[MAX][MAX]; // hdu 3595
int SG(int x,int y){
	if(x > y) swap(x, y);
	if(~sg[x][y]) return sg[x][y];
	if(!x || !y) return sg[x][y] = 0;
	int r = y%x, d = y/x;
	if(d == 1){ // 此时操作唯一
		sg[x][y] = SG(r,x) ^ 1;
		step[x][y] = step[r][x] + 1;
		return sg[x][y];
	}else{ // 由上述说明知必胜
		step[x][y] = SG(r,x) + 1 + step[r][x]; // (r,x)先手胜的话,需多一步决策
		return sg[x][y] = 1;
	}
}
int main(){
	memset(sg, -1, sizeof(sg));
	while(cin >> n){
		int mx = 0, a, b;
		while(n--){
			cin >> a >> b; // 每个单一游戏的两堆石头数
            SG(a, b);
			mx = max(mx, step[a][b]);
		}
        puts("%s", mx&1 ? "MM" : "GG");
	}
	return 0;
}

4.翻硬币游戏

n n n 枚硬币排成一排,依次编号 1 1 1 N N N ,有的正面朝上,有的反面朝上,

现在按照一定的规则翻硬币,

比如每次只能翻一枚或者两枚,或者每次只能翻动连续的几枚,

但是要求最靠右的硬币必须从正面被翻到了反面,

操作集合为空者负,

求必胜策略

给出结论:

当前局面的 S G SG SG 值是所有正面朝上的硬币单独存在时的 S G SG SG 值的异或和

结论的来源估计也是打表猜结论和归纳大法

不过这个结论可以直接用,配合状压或者别的算法可以出很多题目

5.无向图删边游戏

给定一个 n n n 个节点的有根树,

两人轮流删边,删去边之后,不和根节点联通的部分都会被移除

不能操作者输,

求必胜策略

给出结论:

叶子节点的 S G SG SG 值为 0 0 0 ,其他所有节点的 S G SG SG 值为它所有儿子的 S G SG SG 值加 1 1 1 后的异或和

可以参考 克朗原理 的证明,配合归纳法,假设 n n n 节点树成立,那么 n + 1 n+1 n+1 节点树也成立

同时,树的删边游戏可以进一步扩展,感兴趣的同学可以参考 F u s i o n   P r i n c i p l e Fusion \space Principle Fusion Principle

七、致谢与感悟

忙活了一整天,终于完结撒花了

学到了很多东西,对其内在数学模型有了更深的了解,也熟悉了一些常见处理手段(打表、归纳)

同时也收集了许多关于 S G SG SG 函数应用的代码模板和应用模型,真的收获颇丰

下面给出一些有用的链接,在写作时参考了很多文章来源地址https://www.toymoban.com/news/detail-425456.html

  • 《组合游戏略述——浅谈SG游戏的若干拓展及变形》贾志豪 本文参考了许多许多
  • 博弈论ACM / OI_繁凡さん的博客 里面总结的特别全面
  • 博弈论知识汇总 solvit 里面介绍了本文未提到的 N i m K NimK NimK S t a i r N i m StairNim StairNim
  • 博弈论题目总结(一) 和 博弈论题目总结(二) 分别介绍了经典博弈和 S G SG SG 函数应用的大量例题
  • 博弈论总结_Ethan-Walker的博客 里面包含了 80 余道博弈习题,涉及了博弈的方方面面
  • ACM-ICPC中博弈论的一些小小总结_phython96的博客 也介绍了一些本文未出现的思想方法和模型

到了这里,关于博弈论算法常见模型整理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 汤姆·齐格弗里德《纳什均衡与博弈论》笔记(4)博弈论与人性

    第五章 弗洛伊德的梦——博弈和大脑 大脑和经济学 曾经有一段时间——就像在弗洛伊德的年代——心理学家们无法准确地回答人类行为背后的大脑机制。但随着现代神经科学的兴起,情形改变了。比如,人类的情绪不再像过去一样是个谜。科学家们可以观察当人们感到轻蔑

    2024年01月25日
    浏览(54)
  • 【学习笔记】博弈论 ---- 非偏博弈

    本篇按照 Qingyu 在省集讲的加入我这个萌新的萌新理解而成。 听了 Qingyu 的博弈论讲解,感觉我之前学过的博弈就是冰山一角。 由于有一些东西没听懂,就主要写写我听懂的部分,没懂得以后再说吧。 所以这篇只是一个入门,关于博弈的一些习题可能会咕咕咕。 几个基本定

    2024年02月07日
    浏览(56)
  • 博弈论 | 斐波那契博弈

    博弈论是二人或多人在平等的对局中各自利用对方的策略变换自己的对抗策略,达到取胜目标的理论。博弈论是研究互动决策的理论。博弈可以分析自己与对手的利弊关系,从而确立自己在博弈中的优势,因此有不少博弈理论,可以帮助对弈者分析局势,从而采取相应策略,最终达到

    2024年02月12日
    浏览(43)
  • 汤姆·齐格弗里德《纳什均衡与博弈论》笔记(7)博弈论与概率论

    第十一章 帕斯卡的赌注——博弈、概率、信息与无知 在与费马就这个问题的通信过程中,帕斯卡创造出了概率论。另外,帕斯卡在进行严谨的宗教反思中,得出了 概率 这个概念,它在此几百年后,成为一个关键的、对博弈论的提出有重要意义的数学概念。 帕斯卡观察到,

    2024年01月25日
    浏览(52)
  • 博弈论-策略式博弈矩阵、扩展式博弈树 习题 [HBU]

    目录 前言: 题目与求解 11.请将“田忌赛马”的博弈过程用策略式(博弈矩阵)和扩展式(博弈树)分别进行表示,并用文字分别详细表述。 34.两个朋友在一起划拳喝酒,每个人有4个纯策略:杠子、老虎、鸡和虫子。 输赢规则是:杠子降老虎,老虎降鸡,鸡降虫子,虫子降

    2024年02月03日
    浏览(49)
  • 【博弈论笔记】第二章 完全信息静态博弈

    此部分博弈论笔记参考自经济博弈论(第四版)/谢识予和老师的PPT,是在平时学习中以及期末备考中整理的,主要注重对本章节知识点的梳理以及重点知识的理解,细节和逻辑部分还不是很完善,可能不太适合初学者阅读(看书应该会理解的更明白O(∩_∩)O哈哈~)。现更新到

    2024年02月10日
    浏览(51)
  • Nim游戏博弈论

    https://www.luogu.com.cn/problem/P2197 甲,乙两个人玩 nim 取石子游戏。 nim 游戏的规则是这样的:地上有 n n n 堆石子(每堆石子数量小于 1 0 4 10^4 1 0 4 ),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取。每次只能从一堆里取。最后没石子可取的人就输了

    2024年02月15日
    浏览(47)
  • 博弈论入门

    古诺双寡头模型的条件 市场中有且仅有两家公司 策略为同质商品的量, q i q_i q i ​ 边际成本为c,生产成本就为c*q,在这里我们的边际成本是常数。 需求曲线: P = a − b ∗ ( q 1 + q 2 ) P=a-b*(q_1+q_2) P = a − b ∗ ( q 1 ​ + q 2 ​ ) 利润: U 1 ( q 1 , q 2 ) = P ∗ q 1 − c ∗ q 1 , U 2 (

    2024年02月02日
    浏览(45)
  • 博弈论小课堂:零和博弈(找到双方的平衡点)

    从概率论延伸出来的课题——博弈论,博弈论中最典型的两大类博弈,是“零和博弈”与“非零和博弈”。博弈论所研究的最优化问题有多方参与,因此最优化的策略要考虑对方的行为。 博弈论通常被认为是冯·诺依曼发明的,博弈论从本质上讲,是一套解决最优化问题的方

    2024年02月09日
    浏览(44)
  • 台阶型Nim游戏博弈论

    https://www.acwing.com/problem/content/894/ 现在,有一个 n n n 级台阶的楼梯,每级台阶上都有若干个石子,其中第 i i i 级台阶上有 a i a_i a i ​ 个石子( i ≥ 1 i ge 1 i ≥ 1 )。 两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。 已经拿到

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包