博弈问题
所讨论的博弈问题满足以下条件:
- 玩家只有两个人,轮流做出决策,且操作公平。
- 游戏的状态集有限,保证游戏在有限步后结束.
- 博弈双方都使用最优决策。
一个游戏有两个状态,我们称为必胜态和必败态,他们的关系:
- 必胜态表示,从当前状态可以转移到一个必败态。
- 必败态表示,从当前状态无法转移到一个必败态。
也就是说,一个状态不是必胜态,就是必败态。
知识点
SG函数
其中 y 是
游戏的和
游戏
x1,x2,...,xn
的和为
x
,且
理解为
x
是由
SG定理
如果一个游戏的所有子游戏相互独立(即一个子游戏的操作不会影响其他的子游戏),那么
文字表述为,一些游戏的和的 SG 函数等于各个游戏 SG 函数的亦或和。
题目
BZOJ 2463 [中山市选2009]谁能赢呢?
思路:
可以证明,偶数的棋盘一定会被 1×2 的牌覆盖,奇数的棋盘一定可以被 1×2 的牌覆盖多出一个,所以说偶数的棋盘先手必胜,因为它只要走牌的后一个点一定可以赢,反之,奇数的棋盘先手必败。
代码:2463.cpp
BZOJ 1115 [POI2009]石子游戏
思路:
差分以后,就是经典的阶梯 Nim 取石子的模型,后面的端点。
代码:1115.cpp
BZOJ 4202 石子游戏
思路:
类似于阶梯
Nim
游戏,对于一个点为根来说,所有深度与其的差是偶数的点是无效的,因为当
A
做了这个操作以后,另一方
动态加点需要
现在还有最多取
m
个的限制,可以从
换种角度看,
m+1
是一个特殊的取值,这个值一次一定去不到,两次一定可以取完,所以说大于
m+1
的点,先手进行一次取值,后手可以紧跟着再
%m+1
的地方移动一次,便到前面模
m+1
同余的一样的地方去,这样的操作是没有意义的,所以说可以把权值
%(m+1)
,直接按上面的步骤做完即可。
代码:4202.cpp
BZOJ 4347 [POI2016]Nim z utrudnieniem
思路:
如果再取走之后,剩余的石子堆的疑异或和为
0
,那么当前的选择就是一种合法的方案。
所以问题转换为求异或和为
状态:
转移:
如果我们对
a
数组进行排序,那么每次异或和的最大值是
这样算下来,总的时间复杂度是
O(md)
的。
但是这个题的空间限制是
64MB
,只滚动第一维还是不够的,所以可以直接像背包那样,倒着转移,直接省去第一维,但是
0
需要从
代码:4347.cpp
BZOJ 4600 [Sdoi2016]硬币游戏
思路:
代码:4600.cpp
BZOJ 4134 ljw和lzr的hack比赛
思路:
首先划子游戏,拔一颗子树看成一个子游戏,显然,子游戏之间是互相独立的。
一个决策的状态值是以这个点到跟的路径上的所有点的非本链上的孩子为根的子游戏的异或和。
子树的
所以我们用二进制
Trie
来维护异或和与
mex
操作,
Trie
的节点记录当前的子树内已有的点的个数。每一棵树记录一个永久化的标记,标记代表对整棵树的异或。
对原树进行
dfs
,所有的
Trie
进行启发式合并,对于最大树的修改,直接打标记,其他树的元素直接全部插入到大树当中。
统计答案时,记录当前点的所有子树的异或和,向下
dfs
的子树,把子树对应的异或消掉,继续向下搜。