当前位置: 首页 > news >正文

简单博弈

巴什博弈

问题:\(2\) 人玩游戏,共有 \(n\) 个石子,每人每次可以取 \([1,k]\) 个石子,最后一次取石子的人获胜,问先手何时必胜?

结论:巴什博弈先手必败,当且仅当 \((k+1)\mid n\),否则先手必胜。

证明:分类讨论。

  1. \(n\le k\):这时候先手可以一次性取完;
  2. \(n=k+1\):这时候先手无论取 \(x\in[1,k]\) 中的多少个石子,后手都可以一次取完剩余的 \(n-x\) 个石子;
  3. \(n=\lambda(k+1)\):这时候对于每个 \(k+1\) 的石子,情况与 2 同,结果就是后手胜;
  4. \(n=\lambda(k+1)+\mu,\mu\in[1,k]\):这时候,先手可以先把 \(\mu\) 个石子取走,转化为第 3 种情况,此时这里的“先手”变成了情况 3 中的“后手”,故其必胜。

Nim 博弈

定义:给定 \(n\) 堆物品,第 \(i\) 堆物品有 \(A_i\) 个。两名玩家轮流行动,每次可以任选一堆,取走任意多个物品,可把一堆取光,但不能不取。取走最后一件物品者获胜。两人均采取最优策略,问先手能否必胜。我们把这种游戏称为 Nim 博弈

基本概念:

局面:我们把 Nim 博弈游戏过程中面临的状态称为局面

先手与后手:整局游戏第一个行动的称为先手,第二个行动的称为后手

必胜局面与必败局面:若在某一局面下存在某种行动,使得行动后对手面临必败局面,则称这样的局面为必胜局面;若在某一局面下无论采取何种行动,都会输掉游戏,则称这样的局面为必败局面

Nim 博弈不存在平局,只有先手必胜和先手必败两种情况。

Nim 定理:

内容:记 \(\displaystyle A=\bigoplus^{n}_{i=1}A_i\),Nim 博弈先手必胜,当且仅当 \(A\neq 0\)

证明:数学归纳法。

所有物品被取光是一个必败局面,此时显然有 \(A=0\)

对于任意一个局面,如果 \(A\neq 0\),设 \(A\) 的二进制表示下最高位的 \(1\) 在第 \(k\) 位,那么至少存在一堆物品 \(A_i\),它的第 \(k\) 位是 \(1\)。显然 \(A_i\oplus A<A_i\),我们就从 \(A_i\) 堆中取走若干物品,使其变为 \(A_i\oplus A\),就得到了一个各堆物品数量异或和为 \(0\) 的局面。

对于任意一个局面,如果 \(A=0\),那么无论如何取物品,得到的局面下各堆物品数量异或和一定不为 \(0\)。可以用反证法证明,假设 \(A_i\) 被取成了 \(A^{'}_i\),并且 \(A_1\oplus A_2\oplus ...\oplus A^{'}_i\oplus ...\oplus A_n=0\),由异或运算性质知 \(A_i=A^{'}_i\),与 Nim 博弈游戏规则(不能不取)矛盾。

综上所述,由数学归纳法可知,\(A\neq 0\) 为必胜局面,一定存在一种行动使得对手面临“各堆物品数量异或和为 \(0\)”的局面。\(A=0\) 为必败局面,无论如何行动,都会让对手面临一个“各堆物品数量异或和不为 \(0\)”的必胜局面。

例题:P2197 【模板】Nim 游戏

板子题。根据 Nim 定理,当石子数量异或和不为 \(0\) 时,存在先手必胜策略,反之不存在。

代码如下(时间复杂度 \(O(Tn)\)):

#include<bits/stdc++.h>
#define int long longusing namespace std;const int N = 1e4 + 10;int T, n;
int a[N];
int Nimsum;//Nim和 signed main()
{cin >> T;while(T --){Nimsum = 0;cin >> n;for(int i = 1; i <= n; i ++){scanf("%lld", &a[i]);Nimsum ^= a[i];}if(Nimsum != 0){puts("Yes");}else{puts("No");}}return 0;
}

公平组合游戏(ICG)与有向图游戏

公平组合游戏(ICG):

若一个游戏满足:

  1. 由两名玩家交替行动;
  2. 在游戏进程的任意时刻,可以执行的合法行动与轮到哪名玩家无关;
  3. 不能行动的玩家判负。

则称该游戏为公平组合游戏(ICG)

Nim 博弈是一种公平组合游戏。

有向图游戏:

定义:给定一个 DAG,图中有一个唯一的起点,在起点上放有一枚棋子。两名玩家交替地把这枚棋子沿有向边进行移动,每次可以移动一步,无法移动者判负。该游戏被称为有向图游戏

任何一个公平组合游戏都可以转化为有向图游戏。具体方法是:把每个局面看成图中的结点,并且从每个局面向沿着合法行动能够到达的下一个局面连有向边。

博弈图:类似有向图游戏地,将博弈中所有可能的局面(状态)按递推关系画成一张 DAG,就是博弈图

\(\text{mex}\) 运算与 \(\text{SG}\) 函数

\(\text{mex}\) 运算:

定义:设非空整数集 \(S\),定义 \(\text{mex}(S)\) 为求出不属于 \(S\) 的最小非负整数的运算。

用公式表达为:

\[\boxed{\text{mex}(S)=\min_{x\in \mathbf{N},x\notin S}\{x\}} \]

\(\text{SG}\) 函数:

定义:在有向图游戏中,对于每个结点 \(x\),设从 \(x\) 出发共有 \(k\) 条有向边,分别到达结点 \(y_1,y_2,...,y_k\),定义函数 \(\text{SG}(x)\)\(x\) 的后继结点 \(y_1,y_2,...,y_k\)\(\text{SG}\) 函数值构成的集合再执行 \(\text{mex}\) 运算的结果。

用公式表达为:

\[\boxed{\text{SG}(x)=\text{mex}(\left\{ \text{SG}(y_1),\text{SG}(y_2),...,\text{SG}(y_k)\right\})} \]

特别地,整个有向图游戏 \(G\)\(\text{SG}\) 函数值被定义为有向图游戏起点 \(s\)\(\text{SG}\) 函数值,即:

\[\boxed{\text{SG}(G)=\text{SG}(s)} \]

有向图游戏的和:

\(G_1,G_2,...,G_m\)\(m\) 个有向图游戏。定义有向图游戏 \(G\),它的行动规则是任选某个有向图游戏 \(G_i\),并在 \(G_i\) 上行动一步。\(G\) 被称为有向图游戏 \(G_1,G_2,...,G_m\) 的和。

有向图游戏的和的 \(\text{SG}\) 函数值等于它包含的各个子游戏 \(\text{SG}\) 函数值的异或和,即:

\[\boxed{\text{SG}(G)=\bigoplus^{m}_{i=1}\text{SG}(G_i)} \]

有向图游戏的胜负判定:

定理:有向图游戏的某个局面必胜,当且仅当该局面对应结点的 \(\text{SG}\) 函数值大于 \(0\);有向图游戏的某个局面必败,当且仅当该局面对应结点的 \(\text{SG}\) 函数值等于 \(0\)

证明与 Nim 博弈方法类似。

例题

例题 \(1\):取石子游戏 1。

巴什博弈板子:

#include<bits/stdc++.h>using namespace std;int n, k;int main()
{cin >> n >> k;if(n % (k + 1)){puts("1");}else{puts("2");}return 0;
}

例题 \(2\):移棋子游戏。

根据 \(\text{SG}\) 定理,本题所有 \(k\) 个给定节点的 \(\text{SG}\) 函数值的异或和为 \(0\) 时答案为 lose,否则为 win

注意求 \(\text{SG}\) 函数的实现,我们采用了记忆化搜索的方式避免冗余统计:

#include<bits/stdc++.h>using namespace std;const int N = 2e3 + 10;int n, m, k;
vector<int> e[N];int mex(set<int> S)
{int res = 0;while(S.find(res) != S.end()){res ++;}return res;
}int sg[N];int SG(int u)
{if(sg[u] != -1){return sg[u];}set<int> S;for(auto i : e[u]){S.insert(SG(i));}return sg[u] = mex(S);
}int SGsum = 0;int main()
{cin >> n >> m >> k;for(int i = 1; i <= m; i ++){int u, v;scanf("%d%d", &u, &v);e[u].push_back(v);}memset(sg, -1, sizeof sg);for(int i = 1; i <= k; i ++){int u;scanf("%d", &u);SGsum ^= SG(u);}if(SGsum == 0){puts("lose");}else{puts("win");}return 0;
}

例题 \(3\):BeiJing 2009 WC 取石子游戏。

在常规 Nim 博弈的基础上增加了取石子数量的限制集合,我们可以称这种类似 Nim 博弈的游戏为 exNim 博弈

exNim 问题的一般解法是:通过有向图预处理 \(\text{SG}\) 函数,从而转化为 Nim 游戏求解。

对于本题,我们可以根据石子堆中石子数量 \([1,1000]\)\(1000\) 个状态,并计算当前状态的 \(\text{SG}\) 函数值,将题目中的若干 \(A\) 值视为关键节点,根据 \(\text{SG}\) 定理,所有关键点的 \(\text{SG}\) 函数值的异或和为 \(0\) 则无必胜策略,反之有必胜策略。

#include<bits/stdc++.h>using namespace std;const int N = 1e3 + 10;int n, m;
int A[N], B[N];
int S[N];//set
int SG[N];
int SGsum = 0;int main()
{cin >> n;for(int i = 1; i <= n; i ++){scanf("%d", &A[i]);}cin >> m;for(int i = 1; i <= m; i ++){scanf("%d", &B[i]);}for(int i = 1; i <= 1000; i ++){for(int j = 1; j <= m; j ++){if(i < B[j]){continue;}S[SG[i - B[j]]] = i;}for(int j = 0; j <= 1000; j ++){if(S[j] != i){SG[i] = j;break;}}}for(int i = 1; i <= n; i ++){SGsum ^= SG[A[i]];}if(SGsum == 0){puts("NO");}else{puts("YES");for(int i = 1; i <= n; i ++){for(int j = 1; j <= m; j ++){if(A[i] < B[j]){continue;}if(SG[A[i] - B[j]] == (SGsum ^ SG[A[i]]))//N-set{printf("%d %d", i, B[j]);return 0;}}}}return 0;
}
http://www.hskmm.com/?act=detail&tid=17018

相关文章:

  • 从 “纸笔清单” 到全栈引擎:数据填报与类 Excel 控件如何重塑企业效率曲线 - 详解
  • 触摸IC原厂 VKD223EB是一款低电流1通道触控1按键触摸芯片 HBM静电大于5KV
  • 09_五大IO模型
  • wsl Ubuntu 使用cmake
  • 做题笔记总板
  • day 4
  • AI元人文思想体系:从哲学基础到价值原语博弈的微观机制
  • 做题笔记16
  • 条件判断语句
  • EXCEL 行列转换
  • 做题笔记6
  • 第17章 Day20-Day21 逆向爬虫之瑞数6
  • 基于多假设跟踪(MHT)算法的MATLAB实现
  • ROS2之消息接口
  • Linux grep cut tomcat logs
  • Vona ORM分表全攻略
  • 如何在预算与风险之间做选择 iOS 混淆(源码混淆 vs IPA 混淆)的成本-收益分析与实战决策框架
  • 【兰州大学主办|EI稳定检索】第二届信息光学与光电技术国际学术会议(CIOT 2025)
  • 深入解析:设计模式-状态模式详解
  • 【IEEE出版】第五届网络通信与信息安全国际学术会议(ICNCIS 2025)
  • 第16章 Day19 Charles安装和使用---微信小程序逆向
  • DBLINK的创建和使用(总结)
  • Could not resolve host: mirrorlist.centos.org
  • axi 4k边界检测
  • GOSIM 开源出海工作坊:给开源创业者的忠告
  • 华为,让金融智能体月映千江 - 指南
  • 轻量级架构决策记录工具 - ADR Tools
  • 一文搞懂Flex弹性布局空间分配规则
  • AT_agc012_c [AGC012C] Tautonym Puzzle 题目分析
  • 详细介绍:回调函数与错误处理