【笔记】博弈论DP基础——简单记忆化的二人博弈类型和sg函数的组合博弈类型

例题

A , B进行游戏。A先开始,轮流将n减去{2,3,4,5,6}中的一个数,谁最后无法进行减法了,就输了。
给定n。A,B都采用最优策略,问A是否会赢。

状态

设f[i]表示当前的数是i的时候,对于当前的先手来说是否会赢
f[i]=true,则赢
f[i]=false,则输

转移

当先手A操作一次后,问题转移为了对于当前先手B,对(n-i)进行操作

必胜转移到必败,必败转移到必胜

就是说
从f[i]转移到的所有状态f[i-2],f[i-3]..f[i-6]如果都是必胜态,那么f[i]则为必败态
从f[i]转移到的所有状态f[i-2],f[i-3]..f[i-6]如果有一个是必败态,那么f[i]则为必胜态

初始化

f[0]和f[1]对于先手来说必败
f[0]=false,f[1]=false
f[2]则对于先手来说必胜,f[2]=true

碎碎念

前几天上数学课的时候老师讲了一个类似的题,当时想到了DP。

高级

当n%8=1或0时,必败。否则必胜

博弈DP的特征

博弈DP解决的是两人轮流操作,且没有平局的#两人博弈游戏#
写代码的话一般是#人人为我#类型,即用其他状态向自己转移
更一般的,博弈没有固定搜索顺序,习惯用记忆化搜索

problem1【第一类,两人博弈类型】

状态

f[i][j]表示当前手上数字为i,上一个减去的数是j的时候是必胜还是必败

转移

f[i][j]转移到f[i-r][1~r],其中1<=r<=k*j

复杂度

O(n^3)
没有代码

problem2-1【第二类,组合两人博弈类型】

A,B两人游戏,现在有a1,a2,...an共n个数, 轮流操作,每次可以对任意一个数操作,最后谁无法操作谁就输了。操作为将这个数减去{1,2,3,4,5,6}中的一个。

范围:n<=\(10^5\),a_i<=\(10^5\)

分析

相当于有n个#二人博弈问题#,称之为#组合二人博弈问题#

状态

初始蒟蒻
设计一个n维的f[1][2][3]...[n],表示当前
这玩意肯定不行,所以要用sg

mex运算

设S 表示一个非负整数集合。定义mex(S)为求出不属于集合S 的最小非负整数的运算。即:
mex(S) = min{x|x\(\in\) N, x$\notin\S}, 比如mex{0,2,3} = 1

sg函数(Sprague-Grundy 是两个人的名字)

sg[i]表示的是数字i这个状态的sg值
sg值:取出所有能转移到的sg值的前继状态集合{sg[1],sg[i-2]...sg[i-6]},则i的sg函数的值为这个集合的mex运算结果,即sg=mex{sg[1],sg[i-2]...sg[i-6]}

必败态的sg为0,必胜态的sg值为非零

对于这个题,sg[0]必败,所以s[0] = 0,s[1]的前继状态的集合为{s[0]},所以sg[1] = 1
sg[2]的前继状态集合为{sg[0] = 0,sg[1] = 1},sg[2] = 2
sg[3]的前继状态集合为{sg[0] = 0,sg[1] = 1,sg[2] = 2},sg[3] = 3
sg[4] = 4,sg[5] = 5,sg[6] = 6
sg[7]的状态集合为{sg[1] = 1, sg[2] = 2, sg[3] = 3,sg[4] = 4, sg[5] = 5, sg[6] = 6},sg[7] = 0
sg[8] = 1,sg[9] = 2
事实上,对于sg[8]和sg[9],先手必须把状态转移到sg[7],让下一个人必败

对于这个题,有sg值就可以不用n维了吗?不行。他还是这个样子:
sg[a1][a2]...[an]

sg定理

n个游戏的sg值 等于 每个游戏的sg值异或起来
sg(a1,a2...an) = sg(a1) xor sg(a2) ... xor sg(an)

所以我们分开讨论每个游戏,最后异或起来

没有代码

problem2-2——NIM游戏

n <= \(10^5\) a_i <= $10^9¥

其余一些问题可转化为两人博弈或组合博弈问题

posted @ 2020-04-05 00:00  _Buffett  阅读(691)  评论(0编辑  收藏  举报