MnZn 的DP杂篇
前言
一切仅为个人理解,一点都不严谨,若有误请大佬指出 orz
乱七八糟的
转移多的区间DP之去重
首先,这是很显然的区间 DP 。但是只建两维状态就需要去重,作为一个蒟蒻我最不喜欢的就是去重了,所以可以再给状态多设一维方便转移
根据题意,新开的一维代表了当前括号序列的六种状态(详见第一篇题解),只要转移足够好就可以做到不重不漏
那么怎么转移呢。不同的状态可能会有相同的组成成分,要是在利用这相同组成成分转移时将两者都算了进去就会算重,所以可以利用最靠后的某种结构来转移
example.现在要转移*()*()
,那么看似我们需要从*(),*()
与*()*,()
与**,()*()
转移,但这样就会愉快地算重。所以就把最右边的()
看作一个单位,它左边可以与*()
相连,也可以与*()*
相连,这样转移就没问题了
区间DP之一个人来回跑
和关路灯属于同一种题。
-
先断环为链,然后看数据范围,这显然是个区间DP,所以肯定会有
两维表示已经走完了的区间。 -
走完了区间可能目前在左端,也有可能在右端,所以再设一维
表示目前在左端点或右端点。 -
根据题意,不一定能取到区间内的所有熊,而能否取到与时间密切相关;数据量不允许将时间放进 DP 状态内(显然也不能离散化),所以可以像某次模拟赛的题那样将答案放进状态中
最后,状态就是
填表法&刷表法
填表法是用之前已经确定的 DP 状态确定现在的 DP 状态,比如石子合并,而刷表法是用现在已经确定的 DP 值更新可能由它转移的 DP 值。
在一些题目中,用刷表法会比填表法更加方便(需每个状态所依赖的状态对它的影响相互独立)。比如在这题中,因为该 DP 状态中包含答案,是否能 +1 需要额外判断,用刷表法转移就更加方便一些
矩阵加速DP
有一些 DP 的转移是以求和的方式转移的,这就说明所有的 DP 状态的值其实都是最开始初始化的那几个值贡献的,只不过是贡献次数不同。
矩阵加速就是利用这个东西,在快速幂(以及三次方)的时间复杂度内求出最开始初始化的每个值贡献的次数来快速计算最终的答案。
比如说,假设真正的 DP 数组滚动后是一维的,相关矩阵是二维的,矩阵第
以这道题为例,很容易列出状态转移方程(这个时候就不要想记搜了……),因为
这道题的矩阵是固定的,在有的题中矩阵要根据输入生成。
质因子状压
首先,300 以内有 62 个质数,可以利用状压维护质因子相关信息(比如CF1114F),往上就没办法直接状压了,比如这道题。
大概有这样一条性质:一个数的质因子最多只能有一个大于自己的算术平方根。在此题中,500 的数据范围内大于等于 23 的质因子最多出现一次,23 以内的质数只有 8 个,所以可以分组转移使得不会有相同大质因子的数在同一集合中(这题方案合法的充要条件为质因子集合不交)
具体地,具有相同大质因子的数要么都在集合 1 中,要么都在集合 2 中,要么都不在,开两个 dp 数组分别记录都在集合 1 \集合 2 中的方案数分别转移,再开一个 dp 数组记录全局的即可(需去重)
计数相关
状态怎么设呢,感觉会有一维代表“选不选”或是与相关性质有关的状态,然后转移的时候考虑这一维是怎样贡献的:是
自带的,还是 贡献的
线段树合并优化 DP
关于调试
调半天发现是线段树的 query 函数没返回值 [龙图问号]
第一次出错的时候就感觉是取模有问题,看了一圈都没看见,结果最后还真是有个地方忘取模了 [龙图疑惑]
首先这显然是树形 DP,因为答案和约束有关,所以状态中还要体现约束
然后有个性质:对于一些约束
考虑从子节点
若不给边
这里有个求和号,可以用个
同时发现,
记
然后就这样乱七八糟不知道为啥对地做完了。
连通性相关的计数DP
怎么做啊怎么做,和连通性有关是吧,先缩个点。缩完点后是树,每个节点内的非割边可以随便选,太好了开始跑树形 DP。
设状态
怎么转移呢怎么转移呢,如果不建军营那连接的那条边就可选可不选,也就是
然后就乱七八糟不知道为什么不重不漏地做完了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】