ICG、Nim游戏、Bouton定理和SG函数

一、 ICG

ICG(Impartial Combinatorial Games),即公平的组合游戏,其定义如下:

  1. 两名选手。
  2. 两名选手轮流行动,每一次行动可以在有限合法操作集合中选择一个。
  3. 游戏的任何一种可能的局面(position),合法操作集合只取决于这个局面本身;局面的改变称为“移动”(move)。
  4. 若轮到某位选手时,该选手的合法操作集合为空,则这名选手判负。

在ICG游戏中,先手不是必胜就是必败。证明过程:

双方互相决策,有限步骤,可以用树来描述,树的每个叶子节点表示对先手而言是必胜或者必败。

则对于树上的每个节点:

  1. 当这个节点轮到先手行动时,若其存在子节点对先手而言必胜,则当前节点对先手而言必胜,否则当前节点对先手而言必败。
  2. 当这个节点轮到后手行动时,若其存在子节点对先手而言必败,则当前节点对先手而言必败,否则当前节点对先手而言必胜。

按照上述过程,可以从决策树的叶子节点开始向根节点向上推出决策树上每个节点对于先手而言必胜还是必败,故先手不是必胜就是必败。

二、 Nim游戏

Nim游戏是ICG的一种,通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。

三、 Bouton定理

假设Nim游戏的石子有n堆,第i堆的石子个数我们用a_i表示,则我们可以使用(a_1, a_2, …, a_n)表示一个Nim游戏的局面。对于(a_1, a_2, …, a_n)的Nim游戏局面,当且仅当a_1 \wedge a_2 \wedge ... \wedge a_n \neq 0时(其中\wedge是按位异或运算),先手必胜。

证明:

  1. 对于a_1 \wedge a_2 \wedge ... \wedge a_n \neq 0的Nim游戏局面(a_1, a_2, …, a_n),我们设a_1 \wedge a_2 \wedge ... \wedge a_n = k。则必存在a_i,其二进制表示在k的最高位上为1(异或运算的性质),且有a_i \wedge k < a_i。则对于当前局面下的先手可以通过合法的移动将第i堆石子取到只剩a_i \wedge k个,那么此时游戏局面变为(a_1, a_2, ..., a_{i-1}, a_i \wedge k, a_{i+1}, ..., a_n),而a_1 \wedge a_2 \wedge ... \wedge a_{i-1} \wedge (a_i \wedge k) \wedge a_{i+1} \wedge ... \wedge a_n = k \wedge k = 0。用一句话来讲,就是异或和不为0的局面一定存在合法移动可以变为异或和为0的局面。
  2. 对于a_1 \wedge a_2 \wedge ... \wedge a_n = 0的Nim游戏局面(a_1, a_2, …, a_n),假设我们将第i堆石子由a_i个取到a_i'个,则有a_i \neq a_i',则必有a_1 \wedge a_2 \wedge ...\wedge a_{i-1} \wedge a_i' \wedge a_{i+1} \wedge ... \wedge a_n \neq 0(可用反证法证明)。用一句话来讲,就是异或和为0的局面无论怎样合法地进行移动,都将转变为异或和不为0的局面。
  3. 对于局面(0, 0, ..., 0),其异或和为0,对于先手而言是必输的局面。
  4. 对于任何异或和不为0的局面,先手只需要按照策略将其转变为异或和为0的局面,就能保证后手永远只能拿到异或和为0的局面。又因为每一次合法的移动都将导致石子个数减少,故总的移动步数是有限的,最终后手将拿到(0, 0, ..., 0)的局面而无石子可拿,故后手必输,先手必胜。反过来即可证,对于任何异或和为0的局面,先手必输。

四、 SG函数

通过SG函数,每个ICG都可以转换成Nim游戏。

SG函数的定义域为ICG的决策树上的所有节点,其具体定义为:SG(x) = mex\{SG(y) | y是x的子节点\},其中mex(minimal excludant)是施加于集合的运算,表示最小的不属于这个集合的非负整数,比如mex\{0, 1, 2, 4 \} = 3mex\{1, 2, 3 \} = 0mex\{\} = 0

对于ICG的决策树上的节点v,我们可以把它想象成一个只有一堆石子,个数为SG(v)的Nim游戏。

对于节点v的子节点u

  1. 根据SG函数的定义,必有SG(v) \neq SG(u)
  2. SG(v) < SG(u),则根据SG函数的定义,u节点必定存在子节点w使得SG(w) = SG(v)。倘若先手尝试使得局面的SG函数值变大,由局面v移动到局面u,则后手必定可以将局面由u转移到w,恢复SG函数值。故先手无有效的手段让局面的SG函数值增大,我们只需要考虑SG(v) > SG(u)的情况。
  3. 对于全体SG(v) > SG(u)的子节点u,其SG函数值将完整覆盖区间[0, SG(v)-1]上的所有整数。我们从局面v移动到局面u,其实相当于在一堆个数为SG(v)的石子上取走若干石子,使剩下一堆个数为SG(u)的石子。

当ICG中存在n个互相不干扰的移动类型时,我们可以将这n种移动类型视为n堆石子,将该ICG视为n堆石子的Nim游戏。运用前面的Bouton定理,该ICG的先手必胜与否的情况可以通过计算每个移动类型下的初始状态的SG函数,并计算这些SG函数值的异或和来得出。

五、例题HDU 1848 Fibonacci again and again

HDU 1848 Fibonacci again and again

这题就是个ICG,其中在三堆石子上取石子的操作可以分成3种互相不干扰的移动类型,故可将该问题转换为3堆石子的Nim游戏。这三堆石子的初始状态为mnp,计算SG(m) \wedge SG(n) \wedge SG(p),若该值不为0则先手必胜,输出“Fibo”,否则先手必败,输出“Nacci”。

参考AC代码:

#include <bits/stdc++.h>
using namespace std;
int f[500] = {1, 2}, mex[1001];
bool used[1001][1001];
int calc_mex(int x) {
    if (mex[x] >= 0) return mex[x];
    if (!x) return mex[x] = 0;
    for (int i=0; f[i]<=x; i++) used[x][calc_mex(x-f[i])] = 1;
    for (int i=0;;i++)
        if (!used[x][i]) return mex[x] = i;
}
int main() {
    for (int i=2;;i++) {
        f[i] = f[i-1] + f[i-2];
        if (f[i] > 1000) break;
    }
    memset(mex, -1, sizeof(mex));
    int m, n, p;
    while (scanf("%d %d %d", &m, &n, &p) && (m || n || p)) {
        int ans = calc_mex(m) ^ calc_mex(n) ^ calc_mex(p);
        printf(ans ? "Fibo\n" : "Nacci\n");
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • 3.感受数学# 上一期的文章里我们仔细研究了Nim游戏,并且了解了找出必胜策略的方法。但如果把Nim的规则略加改变...
    tdeblog阅读 424评论 0 0
  • https://vjudge.net/problem/HDU-3980题意: 两个人在一个由 n 个玻璃珠组成的...
    Gitfan阅读 917评论 0 0
  • http://acm.hdu.edu.cn/showproblem.php?pid=1525 题意:给你两个数,每...
    Gitfan阅读 949评论 0 0
  • 1.必胜必败态介绍# 假设存在一个游戏,游戏双方通过一定相同的策略进行游戏(假设都选择最优策略),直到一方无法进行...
    tdeblog阅读 704评论 1 0
  • 题目描述: 你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉...
    逍遥ii阅读 1,467评论 0 5