基础博弈
下面都是石子游戏,轮流取走物品。
方便起见,称场上
常见的是公平组合游戏:
- 两个玩家轮流决策,均知道游戏的完整信息。
- 以玩家无法行动作为结束标志。
- 游戏一定在有限步结束,且一定能分出胜负。
博弈图和状态
若能将当前局势看作节点,双方的操作看作节点之间的有向边,则博弈可以看作一个图论问题。
若先手必胜,则称该局势为必胜状态;若先手必败,则称该局势为必败状态。
容易验证以下关键结论:
- 定理 1:一个局势必胜当且仅当存在至少一个后继状态必败。
- 定理 2:一个局势必败当且仅当它的所有后继状态必胜。
Nim 博弈
共
原理
对于特殊情况
若先手取走了
考虑证明后手总是能取
将此
对于
由前论述,先手一定存在取走
cpp
bool Nim(const vector<ll> &a, ll n) {
ll ans = 0;
for (auto ai : a)
ans ^= ai;
if (ans == 0)
return true;
return false;
}
bool Nim(const vector<ll> &a, ll n) {
ll ans = 0;
for (auto ai : a)
ans ^= ai;
if (ans == 0)
return true;
return false;
}
Wythoff 博奕
两堆分别有
原理
先手必输的局势称为奇异局势(Cold Position)。
奇异局势可以简单的判断
cpp
const ld phi = 1.6180339887498948482045868343656;
bool Wythoff(ll a, ll b) {
if (a > b)
swap(a, b);
ll t = (ll) (b - a) * phi;
if (t == a)
return false;
return true;
}
const ld phi = 1.6180339887498948482045868343656;
bool Wythoff(ll a, ll b) {
if (a > b)
swap(a, b);
ll t = (ll) (b - a) * phi;
if (t == a)
return false;
return true;
}
所有自然数都出现在奇异局势中,不重不漏。第
其中
SG 函数
Todo