博弈论入门讲解

博弈论,即公平组合游戏,满足下列一些特征:

  • 一场游戏有两个玩家,两个玩家轮流行动,是经典的回合制游戏。
  • 两个玩家的移动按照规则移动,并且两玩家之间的移动不区分身份。
  • 两个玩家按照最优的决策行动,即给定一个局势,能够一开始就区分出先手必胜还是先手必败。

巴什博弈

尼姆博弈

阶梯博弈

斐波那契博弈

巴什博弈

Brave Game HDU - 1846

现在定义两个字母: N N N 为先手必胜, P P P 为先手必败。

在该例题中,每次可以取1~m个石子,现在先假设能够取 m = 3 m=3 m=3 颗石子,画出的 N − P N-P NP 关系图如下:

石子 0 1 2 3 4 5 6 7 8 9 10
状态 P P P N N N N N N N N N P P P N N N N N N N N N P P P N N N N N N

现在解释一下上图:

  • 首先对于石子数为 0 0 0 的时候,该状态无路可走,所以先手必败, P P P 点。
  • 对于石子数为 1 1 1~ 3 3 3 的时候,因为他们都能够通往状态为 0 0 0 的点,所以能够在先手取完后,让后手得到状态 P P P ,既然对手必败了,所以对于自身无疑必胜。
    • 现对于上一点详细介绍:对于一个状态,若其通往的下一个子状态包含 P P P 状态,则本状态必定先手必胜,即 N N N 点。例如上面图示,当石子数为 3 3 3 的时候,可以取一个通往 2 2 2 号点,可以取两个通往 1 1 1 号点,可以取三个通往 0 0 0 号点,其中 0 0 0 号点是 P P P 状态,所以 3 3 3 号点先手必胜。
  • 对于石子数是 4 4 4 的时候,他可以取一个通往 3 3 3 号点,取两个通往 2 2 2 号点,取三个通往 1 1 1 号点;其中这三个子状态都是 N N N 状态,所以 4 4 4 号点先手必败,即 P P P 点。
    • 现对于上一点详细介绍:对于一个状态,若其通往的下一个状态全部都是 N N N 状态,即无论自己怎么决策行动,都能让对手获胜,所以该状态必定先手必败,即 P P P 点。
  • 后面 5 5 5~ 10 10 10 可以根据同样的方法推得,简单明了的说,NP关系推理几乎就是图游戏:通往的下一个状态,即子结点,包含 P P P 状态,则该状态是 N N N 点;若子结点无 P P P 状态,则该状态为 N N N 点。
  • NP关系推理的题目基本上都是通过找规律来解题。在本题中, 显然当 n % ( m + 1 ) = = 0 n\%(m+1)==0 n%(m+1)==0 的时候是 P P P 点,其余情况则是 N N N 点。


尼姆博弈

现通过一道例题引入 S G SG SG 函数:

  • 定义一个数 x x x S G SG SG 值: s g ( x ) = sg(x)= sg(x)= { v ∣ m e x [ s g ( v ) ] {v|mex[sg(v)]} vmex[sg(v)]} ,其中 v v v x x x 可以通往的下个状态点

  • 假设在一局取石子游戏中,能够取 1 , 2 , 4 1,2,4 1,2,4 个石子,并且假设 0 0 0 号点的 S G SG SG 值为0

  • 画出的 s g sg sg 表如下:

石子 0 1 2 3 4 5 6 7 8 9 10
S G SG SG 0 1 2 0 1 2 0 1 2 0 1
  • 对于 4 4 4 号点,取一个通往 3 3 3 号点: s g ( 3 ) = 0 sg(3)=0 sg(3)=0 ;取两个通往 2 2 2 号点: s g ( 2 ) = 2 sg(2)=2 sg(2)=2 ;取四个通往 0 0 0 号点: s g ( 0 ) = 0 sg(0)=0 sg(0)=0 。所以取 m e x [ 0 , 2 ] = 1 mex[0,2]=1 mex[0,2]=1, 所以 s g ( 4 ) = 1 sg(4)=1 sg(4)=1

  • 其余点同理,取 m e x mex mex 即可。

  • 由上图可知, S G SG SG 函数也是有规律可寻。

  • 对于能取 1 , 2 , 4 1,2,4 1,2,4 个石子的 s g sg sg 函数代码如下:

    const int N=1e3+10;
    int sg[N];
    bool vis[N];
    void getSG() {
    	sg[0] = 0;
    	for (int i = 1; i <= 1000; ++i) {
    		memset(vis, false, sizeof vis);
    		//记录通往下一个状态的sg值
    		if (i - 1 >= 0) vis[sg[i - 1]] = true;
    		if (i - 2 >= 0) vis[sg[i - 2]] = true;
    		if (i - 4 >= 0) vis[sg[i - 4]] = true;
    
    		//取mex
    		for (int j = 0;; ++j) {
    			if (!vis[j]) {
    				sg[i] = j;
    				break;
    			}
    		}
    	}
    }
    

Being a Good Boy in Spring Festival HDU - 1850

现假设有 n n n 堆牌,对于一个堆 i i i ,假设该堆的 S G SG SG 值为 s g ( a i ) sg(a_i) sg(ai) ,那么游戏的总状态 S G SG SG = s g ( a 1 ) ⊕ s g ( a 2 ) ⊕ s g ( a 3 ) ⊕ . . . ⊕ s g ( a n ) sg(a_1)\oplus sg(a_2)\oplus sg(a_3)\oplus ... \oplus sg(a_n) sg(a1)sg(a2)sg(a3)...sg(an)

定理

  • 如果 S G ≠ 0 SG≠0 SG=0 ,则该游戏先手必胜,为 N N N 点。

  • 反之如果 S G = 0 SG=0 SG=0 ,则该游戏先手必败,为 P P P 点。

因为本题中,对于一个堆中有 x x x 个数,每次可以从堆中取 [ 1 1 1, x x x] 个数, 所以 s g ( x ) = x sg(x)=x sg(x)=x

关于本题后面输出解的问题,请查看该博客


阶梯博弈

这篇博客讲得不错:传送门

关于阶梯博弈,并没有找到基本的板子题,有个稍微类似的二维题目:Crazy Calendar LightOJ - 1393

变形题:Georgia and Bob POJ - 1704;Climbing the Hill HDU - 4315


关于斐波那契博弈以及 k k k 倍动态减法的详解,请查阅国家集训队论文

例题:A simple stone game HDU - 2486

参考书目

[1]罗勇军,郭卫斌.算法竞赛入门到进阶.

猜你喜欢

转载自blog.csdn.net/bloom_er/article/details/113781154
今日推荐