博弈论笔记
博弈论
公平组合游戏
公平组合游戏(Impartial Game)的定义如下:
游戏有两个人参与,二者轮流做出决策,双方均知道游戏的完整信息;
任意一个游戏者在某一确定状态可以作出的决策集合只与当前的状态有关,而与游戏者无关;
游戏中的同一个状态不可能多次抵达,游戏以玩家无法行动为结束,且游戏一定会在有限步后以非平局结束。 ——— oi-wiki
倒着 dp
Nim 游戏
经典例题
有
结论:
- 对于状态的异或和为 0 的,必然不可能通过一次操作使异或和为 0,因为对于每个要被取的堆,只有当堆的数量不变才能使异或和为 0。
- 对于状态的异或和不为 0 的,必然有一种方案可以使异或和变为 0,可以通过二进制来构造。
- 当所有堆的大小为 0 时,那么必然是必败局面,此处设为初始状态。
那么对于初始状态,可以用一次操作使其变成异或和不为 0 的,再用一次即可变成异或和为 0 的,所以统计异或和,如果异或和为 0 则先手必败,否则先手必胜。
变种
CSES-1099
对于奇数编号台阶的,如果你动它,那么对手可以用同样的方式动回来,当动到 1 时,就动不了了,所以没有贡献;对于偶数编号台阶,如果你动它,会动到奇数编号台阶,就没有贡献了,相当于就是消掉了,那就变回了经典的 Nim 游戏。
SG 函数
SG 函数定义为:所有的后继节点的 SG 函数的 mex,而所有必败节点的 SG 为 0,那么所有的必胜节点的 SG 的值就不为 0。
然而 SG 函数依旧满足 Nim 游戏的三个结论(这里就不再解释了),所以答案求法是一样的。
SG 函数可以用来求答案也可以用来找规律。
例题
CSES-2207
通过找规律我们猜测(嗯,就是猜测)答案为 0 的可能性特别小,所以只要把所有 SG 为 0 的记下来,然后输出时看看 n 是否被记录过 SG 为 0 即可。
所以总的来说就是特别的玄学……
非常好写的博弈论题:CF1823E,不过前期准备可能有点复杂~,也就浅浅代码
#include <iostream> #include <vector> using namespace std; const int MaxN = 2e5 + 10; int n, l, r, sum, ans; vector<int> g[MaxN]; bool vis[MaxN]; void DFS(int x) { if (vis[x]) { return; } vis[x] = 1, sum++; for (int i : g[x]) { DFS(i); } } int main() { cin >> n >> l >> r; for (int i = 1, u, v; i <= n; i++) { cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } for (int i = 1; i <= n; i++) { if (!vis[i]) { sum = 0; DFS(i); if (l <= sum && sum <= (l + r - 1)) { ans ^= sum / l; } } } cout << (ans ? "Alice" : "Bob") << endl; return 0; }
本文作者:yabnto
本文链接:https://www.cnblogs.com/ybtarr/p/17609363.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战