【笔记】简单博弈

前言

大半年前写的东西了,自己真的在走下坡路

例题

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$ otinS}, 比如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¥

problem3-1【第三类,可以转移到组合博弈】

n+1堆石子,最左边一堆石头有2012个,两个人分别进行操作。一次操作可以选取两堆不同的石堆分别增加或减少一个石子(一加一减,或给已经不剩石子的堆加一个都是允许的)。为了保证游戏会在有限步内结束,规定所选的两堆中右边的那一堆一定要包含奇数个石子,无路可走者输.问先手是否必胜?

problem3-2

problem3-3

必败态

除了最左边,每一堆都是偶数个石子,所以不讨论每一堆的实际个数,只讨论奇偶
a1,a2...an等于0或1

problem3-4

不关心石子个数,只关心奇偶
因为独立的是石子而不是石子队
因为我们的游戏单位是石子,两个石子的sg值相互抵消为0,所以只关心奇偶
NIM的游戏单位是石子堆

状态

sg[i]在第i堆的石子的sg值

转移

sg[i] = mex(sg[j]^sg[k])

原文地址:https://www.cnblogs.com/ZhengkunJia/p/13795148.html