博弈论快速入门

一、巴什博奕(Bash Game)

基本描述:

只有一堆n个石子,两个人轮流从这堆石子中取石子,规定每次至少取一个,最多取m个,最后取完的人获胜。

分析:

  1. 当n <= m的时候,显然先手获胜,因为一次就能取完。
  2. 当n = m+1 的时候,由于先手最多取走m个,无论其取走多少个,剩下的后手均可以一次取完,显然后手胜。
  3. 根据以上分析,我们可以将n写成 n = (m+1) * r + s 的形式。对于先手玩家,我们可以取走s个,给对方造成剩下(m+1) 整数倍的情形。此时无论对手取走多少个,假设对手取走k个, 我们一定可以做到取走 (m+1-k)个,此时剩下(m+1) * (r-1)个,那么留给对方又是(m+1)的整数倍,如此就可以保证 先手 取胜。

结论:

  1. 当 n <=m 时,先手必胜。
  2. 当 n % (m+1) = 0时,后手必胜。
  3. 当 n % (m+1) != 0时,先手必胜。

其中上述的情况1和3可以合并,故:

  1. 当 n % (m+1) = 0时,后手必胜。
  2. 当 n % (m+1) != 0时,先手必胜。

注意:

  1. 变形玩法:两个人轮流报数,每次至少1个数,最多报10个数字,谁先报到100取胜。

练习:

  1. HDU 1846
  2. HDU 2149
  3. HDU 2188
  4. HDU 4764

二、PN点分析

什么是PN点

  1. P点,即必败点。前一个选手(Previous player)将取胜的位置称为必败点。
  2. N点,即必胜点。下一个选手(Next player)将取胜的位置称为必胜点。

PN点的属性

  1. 所有终结点均为必败点(P点);
  2. 从任何必胜点(N点)操作,至少有一种方法可以进入必败点(P点);
  3. 无论如何操作,必败点(P点)都只能进入必胜点(N点)。

分析步骤

  1. 将所有终结位置标记为必败点(P点);
  2. 将所有一步能进入必败点(P点)的位置标记为必胜点(N点);
  3. 如果从某个点开始的所有一步操作都只能进入必胜点(N点),则将该位置标记为必败点(P点);
  4. 如果在步骤3中未能找到新的必败点(P点),算法终止,否则返回步骤2.

结论

  1. 当行列都是奇数的时候,一定是必败点;
  2. 否则为必胜点。

注意

  1. 至于结论怎么推出来的,大家画一下3 * 4, 4 * 4, 3 * 3的PN分析图就知道了。

练习

  1. HDU 2147

三、斐波那契博弈

基本描述

有一堆个数为n的石子,游戏双方轮流取石子,满足:

  1. 先手不能再第一次把所有石子取完;
  2. 之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间,包括1和对手取的石子数的2倍。
    取最后石子的人为赢家。

结论

先说结论:
当且仅当n不是Fibonacci数时,先手必胜。换句话说,先手必败构成Fibonacci数列。

分析

证明需要前置技能,“Zeckendorf定理”(齐肯多夫定理),其表述为:任何正整数可以表示为若干个不连续的Fibonacci数之和。

具体证明在这篇博文中给出,有兴趣的读者可以自行学习。

练习

  1. HDU 2516

四、威佐夫博弈

基本描述

有两堆各若干个石子,两个人轮流从某一堆或者两堆中取同样多的物品,规定每次至少取一个,多着不限,最后取完石子的人获胜。

分析

设这两堆石子分别有(A,B)个,并且A<=B。我们先来看一下先手必败的局势。

  1. (0,0) 先手必败,很明显他没得取了。
  2. (1,2) 先手必败。具体分析一下,先手有以下几种取法:
    取第一堆的1个,后手取走第二堆的2个获胜。
    从第一堆第二堆各取1个,后手取走第二堆剩下的1个获胜。
    取第二堆的1个,后手从第一堆第二堆各取1个获胜。
    取第二堆的2个,后手取走第一堆的1和获胜。
    综上所述,先手必败。
  3. (3,5) 先手必败。 首先可以明确的一点是,先手不能把任意一堆取完,如果取完显然必败。
    先讨论先手从第一堆中取的情况
    先手可以从第一堆中取1个,后手从第二堆中取4个,转化为(1,2),先手必败。
    先手可以从第一堆中取2个,后手从第二堆中取3个,转化为(1,2),先手必败。
    再讨论先手从第二堆中取的情况
    先手可以从第二堆中取1个,后手从两堆中各取2个,转化为(1,2),先手必败。
    先手可以从第二堆中取2个,后手从两堆中各取3个,转化为(0,0),先手必败。
    先手可以从第二堆中取3个,后手从两堆中各取1个,转化为(1,2),先手必败。
    先手可以从第二堆中取4个,后手从第一堆中取2个,转化为(1,2),先手必败。
    接着讨论先手从两堆中取的情况
    先手可以从两堆中各取1个,转化为(2,4),此时情况较多
    后手足够聪明,他从第二堆中取了1个,转化为(2,3),先手也足够聪明,他为了不直接输掉,从第一堆中取了1个(其他取法直接输掉了),转化为(1,3),此时后手从第二堆中取1个,转化为(1,2),先手必败。
    先手可以从两堆中各取2个,后手从第二堆中取一个,转化为(1,2),先手必败。
    综上所述,先手必败。
  4. 其他的先手必败局势
    (4,7),(6,10),(8,13),(9,15),(11,18).

  5. 我们将先手必败局势的集合,称为奇异局势。

奇异局势的性质

  1. 任何自然数都包含在一个且仅有一个奇异局势中。
  2. 任意操作都可将奇异局势变为非奇异局势。
  3. 采用适当的方法,可以将非奇异局势变为奇异局势。

Betty定理

我们可以发现,将所有奇异局势按照第一堆的石子的数目从小到大排列,每个奇异局势的差值是自然数列
进一步观察发现,对于一个奇异局势(A,B), A = 下取整[ (B-A) * 1.618 ],更准确的说,1.618 = (sqrt(5) + 1) / 2.

为什么会是这样的? 具体的证明涉及到Betty的定理,有兴趣的读者可以百度,这里不再赘述。

常见的几类问题

  1. 给出一个局面,判断先手输赢。
    检查是否是奇异局势。
  2. 给出局面,判断先手输赢,若赢,求出首步取法。
    由于差值是固定的,根据差值计算。

练习

  1. POJ 1067
  2. HDU 1527
  3. 51NOD 1072
  4. HDU 2177
  5. NYOJ 161

五、尼姆博弈

基本描述

有三堆石子, 每堆有若干个,两个人轮流从某一堆中任取石子,每次至少取一个,多者不限,最后取完者获胜。

分析

用(A,B,C)来表示某一特定局势,同时规定A<=B<=C。奇异局势表示先手必败。

  1. 显然(0,0,0)是奇异局势。
  2. (0,n,n)是奇异局势,当先手拿走s个石子时,我们对应拿走s个石子,最终转化为(0,0,0)。
  3. (1,2,3)也是奇异局势,无论先手如何取,我们都可以转化为(0,n,n)的局势。

对于一个奇异局势(A,B,C),我们可以发现,A(XOR)B(XOR)C = 0。
下面一条需要的前置技能
设有数字a,b,a(XOR)b(XOR)(a(XOR)b) = (a(XOR)a)(XOR)(b(XOR)b) = 0
对于一个非奇异局势(A,B,C),我们只需要将C转化为(A(XOR)B)即可,而将C转化为(A(XOR)B)的操作为,C = C-(A(XOR)B)即可。

注:

  1. 异或在C语言中的符号为^。
  2. 对于此情景来说,可以推广到N堆石子,奇异局势的条件为A1(XOR)A2(XOR)A3(XOR)……AN(XOR) = 0。
  3. A(XOR)B(XOR)B = A,可推广到N个变量,A1(XOR)A2(XOR)A3(XOR)……(XOR)AN(XOR)AN(XOR)AN-1(XOR)……(XOR)A3(XOR)A2 = A1;

练习

  1. HDU 1850

六、SG函数

基本描述

SG函数为计算博弈状态的函数,当SG[X] = 0时,说明先手必败。
为了求解SG函数,首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。
对于任意状态 x , 定义 SG(x) = mex(S),其中 S 是 x 后继状态的SG函数值的集合。如 x 有三个后继状态分别为 SG(a),SG(b),SG(c),那么SG(x) = mex{SG(a),SG(b),SG(c)}。
这样 集合S 的终态必然是空集,所以SG函数的终态为 SG(x) = 0,当且仅当 x 为必败点P时。

说起来很抽象,举一个具体的例子来说明一下。

实例:取石子游戏

游戏规则:

有1堆n个的石子,每次只能取{ 1, 3, 4 }个石子,先取完石子者胜利,那么各个数的SG值为多少?

SG分析

SG[0] = 0(显然没有石子可取时必败);
f[] = {1,3,4}(表示每次取有3中方案,取1个,取3个,取4个);

当石子x = 1时,可以取走1-f{1}个石子,SG[1] = mex(SG[1-1]) = mex(0) = 1;
当石子x = 2时,可以取走2-f{1}个石子,SG[2] = mex(SG[2-1]) = mex(1) = 0;
当石子x = 3时,可以取走3-f{1,3}个石子,SG[3] = mex(SG[3-1],SG[3-3]) = mex(0,0) = 1;
当石子x = 4时,可以取走4-f{1,3,4}个石子,SG[4] = mex(SG[4-1],SG[4-3],SG[4-4]) = mex(1,1,0) = 2;

以此类推…

我们可以打出SG函数的表,根据表来判断是先手必胜还是先手必败。

练习

  1. HDU 1847
  2. HDU 1848

七、更多的练习

  1. POJ 2234
  2. HDU 4388
  3. POJ 2975
  4. HDU 1367
  5. POJ 2505
  6. ZOJ 3057
  7. POJ 2484
  8. POJ 2425
  9. POJ 2960
  10. POJ 1740
  11. POJ 1704
  12. POJ 2068
  13. POJ 3480
  14. POJ 2348
  15. HDU 2645
  16. POJ 3710
  17. POJ 3533
posted @ 2017-08-06 23:49  pengwill  阅读(448)  评论(0编辑  收藏  举报