与[NOI2022] 移除石子有关的dp技巧总结
插头
在插头 DP 中有插头这个概念。
该题用状压的方式存储了轮廓线上的每条边能否与相邻格子连接。
有些题决策之间会互相影响,此时就可以设计类插头。
形式化的,有若干要求形如只有在第
下面给出几道例题,以设计插头的角度去思考:
Neko Rules the Catniverse (Large Version)
不允许重复,根据经典套路枚举值域。
每次插入一个数,这个数只能插在不小于这个数减
此时,前面的决策就会影响到后面的决策,考虑把前面对后面会产生影响的决策塞到状态里。
由于
最后矩阵快速幂优化以下就行了。
Bear and Cavalry
首先将两个数组分别排序后配对的两个数就不会太远。
由于不能重复匹配,所以转移的时候我们要知道有哪些格子还可以用。
由于转移的时候可能会占掉后面的格子,所以前面对后面产生了影响。
于是直接可以将一个格子是否被占用设计成类插头,直接状压,动态 dp 即可。
Gerald and Path
从左往右 dp,在一个点考虑这里的线段往哪个方向延伸。
如果往左延伸则可能会重合。
考虑贡献提前计算,到达一个格子时直接考虑这个格子是否要贡献到答案。
如果这个格子需要贡献到答案,则后面就必须有一个往左延伸到这个位置的线段。
这就类似本文开头的那个模型,设计类插头为当前有哪些格子需要被延伸。
直接这么设计状态量很大,不过可以发现我们只关心需要被延伸到的最靠左的格子,所以直接开一维记录这个格子在哪即可。
对于往右延伸的情况,同样是前面对后面产生影响。把影响记录到状态里,也就是记录当前已经延伸到的最靠右的位置是什么。
于是这就是个三维的 dp 了。
[NOI2023] 桂花树 也用到了此技巧,这里不再赘述。
搜状态
有的题看似状态是指数级别的,但一搜可以发现本质不同的状态数是很少的,就可以以此为出发点进行 dp。
[SDOI2013] 淘金
首先可以发现
直接枚举
Around the World
注意到值域很小,但是如果直接状压每个值是否存在依然不行。
只有异或操作,考虑线性基。
可以看出来本质不同的线性基个数是很少的,搜以下发现不到
dp 套 dp
考虑这样一个问题:
有一个长度为
假设这个问题可以通过简单的 dp 解决。
现在已知第
此问题就可以使用 dp 套 dp 解决。
顾名思义,就是把一整个 dp 数组塞到状态里。
由于这么做复杂度是很高的,一般需要结合搜状态。
Minimal Subset Difference
首先考虑怎么求
用
显然可以 bitset 优化。
然后搜一下发现本质不同的 bitset 只有不超过
于是可以把数组
实现的时候可以先预处理出来转移图。
[NOI2022] 移除石子
它来了。
l_i=r_i,k=0
把操作转化一下。
第二个操作区间长度不小于
相当于要求若干次操作
前面的操作会对后面产生影响,可以设计一个类插头,存储一个每个位置已经被执行了几次操作
搜一下可以发现状态量不到
用
直接 dp 能通过此部分分。
l_i=r_i,k\neq0
类似的,设计
把表打出来可以发现
于是可以把状态优化到两维,用
实际上不优化状态应该也能做,因为本质不同的状态数不变,但是会麻烦一些。
r_i\le 10
考虑 dp 套 dp,搜一下状态发现只有约
预处理出来转移图直接跑即可。
r_i\le 10^9
可以发现当
所以只需要枚举到
总复杂度
总结
[NOI2022]移除石子在场上只有极少数的选手通过,但是在熟悉以上技巧后,推出正解还是比较自然的,并没有什么非常神仙的结论或性质。
是一道 dp 进阶的好题。