@exut
2024-11-01T02:45:57.000000Z
字数 2385
阅读 159
博弈论 数学
SG函数是用于解决博弈论中公平组合游戏(ICG)问题的一种方法
这是啥?
定义大概就几条:
这就是 ICG,公平组合游戏
典型例子是 nim 游戏
必败态:记为 P,直观理解就是到达这个状态的人已经必死无疑了
必胜态:记为 N,直观理解就是到这里就稳了,脑子不犯蠢就一定会赢
可以证明 ICG 里任意状态一定都是这两种状态,有策梅洛定理:
策梅洛定理:ICG 游戏中,任何一个局面先手或者后手其中之一必然存在必胜策略
如何判断一个状态是 N 是 P 呢?
最直观的方法是:
P,称为初必败态有这样一个问题
给定一个有向无环图,在给定的起点处有一个棋子,两个炒鸡聪明的人交替移动这个棋子,不能移动者输
看起来是一个很呆的问题,但是这个问题单独拿出来的意义在于 任意一个 ICG 问题都可以归纳到这种形式(状态为点,状态间连边)
马上要开始探究 SG 函数,但是在此之前......
首先我们需要定义一个奇怪的运算,mex
这是一个数集的运算符号, 代表的是不在集合 中 的最小自然数
例如
用 表示从 到 ,存在直接的有向边,则
对于给定的 DAG,我们定义每个点的SG函数为:
但是只有这一个函数呢,他是啥用么有的
这个应该比较显然的说,因为此时后继状态都是空集
以上就是一维 函数的基本内容,利用这个例子我们可以解决一个简单的经典小问题
巴什博弈:一堆石子有 个,每次可以取 个石子。先取完者获胜。问何时先手必胜,何时后手必胜?
发现暴力算是可以解决的
如果追求效率,经常不会真的去暴力算 ,而是考虑直接归纳每个状态的 函数
如果算一遍 的代价可以承受,就可以考虑直接去算
但是如果不能归纳出 函数,这种博弈问题我们就是不能得出结论通解的
先介绍一下考场实用的一种方法:打表
#include<bits/stdc++.h>using namespace std;const int N=1e5+5;int n,m;int SG[N];bitset<N> S,clr;void get_SG(){SG[0]=0;for(int i=1;i<=n;i++){S&=clr;for(int j=1;j<=min(m,i);j++){S[SG[i-j]]=1;}for(int j=0;;j++){if(!S[j]) {SG[i]=j;break;}}}}int main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>n>>m;get_SG();for(int i=1;i<=n;i++) cout<<SG[i]<<endl;}
根据定义,这份代码可以打出巴什博弈的 函数
我们可以观察出 在巴什博弈的规律是 ,这是我们观察出的结论
一般我们可以打出表来,然后再证明(当然不证也不是啥大事,只要你多看看确认是对的就行)
巴什博弈的证明是显然的,就不赘述了
如果 只能解决一维的博弈问题,那这个玩意其实有点弱了
先用一个简单的例子来引入一下
这是一个可拆分的组合游戏
我们考虑一个子游戏,即考虑拿出任意一堆来做游戏
我们称 表示大小为 的堆的 函数,显然有
我们很容易得出面前的每一堆的子游戏是必胜还是必败
尝试用子问题的胜败推出总问题的胜败!
这里先考虑两个子问题的复合,因为多个子问题本质上就是两个的情况的扩展
当我面前两个游戏都是必败的,则我必败
必败的走一步必然走到必胜的
等会对面再把另一个变成必败的,我又收到了两个必败游戏
最后我会收到两个无子可动的终盘游戏,则我必败
假如我面前摆着一败一胜的游戏,实际上我必胜
必胜的走一步能走到必败的
对面会收到两个必败,对面一定会输
故我必胜
假如面前是两个必胜......
等会,好像不太对劲
两个必胜在我面前时,我根本无法判断我必胜还是必败
有点悲哀,好像寄了,单个的 函数貌似无法直接复合生成,那难道没有办法了吗
此时某位我不知道是谁的伟大的人给出了一个伟大的定理,SG定理
SG定理:游戏的“和”(其实是复合)的 值是各个子问题 的异或和
然后我们可以发现这个问题我们解决了!
于是nim游戏的 已经非常简单的搞定了
代码:
#include<bits/stdc++.h>using namespace std;const int N=1e4+5;int n;int a[N];int T;void work(){cin>>n;int xr=0;for(int i=1;i<=n;i++)cin>>a[i],xr^=a[i];if(xr==0) cout<<"No\n";else cout<<"Yes\n";}int main(){cin>>T;while(T--){work();}}
短小精悍
证明不会
后面是例题环节
here(需要权限)
考察每个数的 ,容易得出 ,其余情况 ,显然 里面那一坨要么大于 要么是 所以 ,然后就做完了