博弈论
公平博弈
一般来说,OI 谈的都是这个。
定义
在任意确定状态下,所有参与者可选择的行动完全相同,仅取决于当前状态,与身份无关。
但象棋、围棋等都是非公平博弈。
模型
有向图游戏
给定一个有向图,起点放一枚棋子,每次一个玩家棋子沿一条边走一步,谁先不可走则输。
-
先看 DAG 情况:
可以用 DP 解决:
设 \(dp_u\) 的值 \(1\) 表示先手必胜, \(0\) 表示先手必败。
则有 \(dp_u = 1 \iff \exists v (u \to v) dp_v=0\)。
\(dp_u = 0\) 同理。
则有 \(dp_u = !(dp_{v1} \& dp_{v2} \& \cdots)\)。
-
对于一般图
存在一种情况,叫做 和棋。
设 \(dp_u\) 的值 \(1\) 表示先手必胜, \(-1\) 表示先手必败,\(0\) 表示和棋。
- \(u\to i, \exists i,dp_i=-1 \iff dp_u=1\);
- \(u\to i, \forall i,dp_i=1 \iff dp_u=-1\);
- \(u\to i, \forall i,dp_i=1/0 且不全为 0\iff dp_u=0\)。
接下来,处理环的情况
对于能判断的直接推,不能推的就放过。
例题
就是板子。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, q;
int in[N], ind[N];
vector<int> e[N];
int ans[N];
bool vis[N];
int main(){
scanf("%d%d%d", &n, &m, &q);
for(int i = 1, u, v; i <= m; i ++) scanf("%d%d", &u, &v), e[v].emplace_back(u), ind[u] ++; // 建反图
while(q --){
int s, t; scanf("%d%d", &s, &t);
memset(ans, 0, sizeof ans);
memset(vis, false, sizeof vis);
ans[t] = -1;
for(int i = 1; i <= n; i ++) in[i] = ind[i];
queue<int> q; q.emplace(t);
for(int i = 1; i <= n; i ++) if(in[i] == 0 && i != t) ans[i] = -1, q.emplace(i); // 拓扑板子
while(!q.empty()){
int u = q.front(); q.pop();
if(vis[u]) continue;
vis[u] = 1; // 拓扑板子
if(ans[u] == -1) for(auto v : e[u]) ans[v] = 1, q.emplace(v); // 针对必败到必胜
else { // 对于必败,到所有点都必胜,则必败
for(auto v : e[u]){
in[v] --;
if(in[v] == 0) ans[v] = -1, q.emplace(v); // 已经确认所有点都已确定状态
}
}
}
printf("%d\n", ans[s]);
}
return 0;
}
棋类
局面有限,并且当前局面可以转化为确定的下一个局面则可以转移。
将当前局面和哪方先手打包成一个二元组,就转化成了一个有向图游戏。
Nim 游戏
有一堆石子,每次可以取任意一堆任意多石子(不能不取),谁不能取谁输。
先放结论:
记 \(S = a_1 \oplus a_2 \oplus \cdots\),则若 \(S = 0\) 先手必败,否则先手必胜。
证明:
-
先手必败 \(\iff \forall\) 后继有先手必胜;
-
先手必胜 \(\iff \exists\) 后继有先手必败。
CODE:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n;
int a[N];
int main(){
int t = 0; cin>>t;
while(t --){
int ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
ans ^= a[i];
}
puts(ans == 0 ? "No" : "Yes");
}
return 0;
}
用途
求有向图游戏的和。
让我们只讨论 DAG。
定义 \(SG_u = mex\{SG_v, u\to v\}\)。
则我们仿照 Nim 游戏:
计算 \(X = \oplus SG_u\),若 \(x = 0\) 则先手必败,否则先手必胜,其中 \(u\) 为所有有向图游戏的起点。
由此得到推论:
有 \(n\) 个相同的图,若 \(n\) 为奇数,则与单图情况一样,若 \(n\) 为偶数,则先手必败。
-
SG 的证明:
若 \(SG = x\)。则可以转移到 \(\forall y\) 类状态 \((y < x)\)。
其中 \(x\) 类状态表示最坏 \(x\) 步游戏结束。
那么这个 \(SG\) 就和 Nim 游戏一样。
故上述结论成立。

浙公网安备 33010602011771号