部分 DP 技巧
决策单调性优化 DP
分治做法
考虑如下转移
若 \(i\) 的最优决策点满足决策单调性,那么可以分治优化。
考虑分治函数 solve(l,r,x,y) 表示 \(f_l\sim f_r\) 的最优决策点在 \([x,y]\)。设 \(mid=\lfloor \frac{l+r}{2}\rfloor\),那么可以暴力求出 \(f_{mid}\) 的最优决策点之后向下分治。复杂度显然为 \(O(n\log n)\)
当转移形式如
分治就需要再套一个 CDQ 了。复杂度双 \(\log\)
二分单调栈/单调队列
用队列维护每个点作为最优决策点的区间,每次用 \(i\) 的最优决策区间覆盖队尾的区间即可。覆盖时需二分,复杂度 \(O(n\log n)\)
CF1603D Artistic Partition
先给 \(c(l,r)\) 预处理后缀和可以做到 \(O(n\sqrt{n})-O(1)\) 查询。接下来的决策单调性是较为易证的。
注意到若 \(2l>r\),那么 \(c(l,r)\) 一定能取到最小值 \(r-l+1\),所以当 \(k\) 足够大时,直接输出即可,否则直接连续段 DP+决策单调性优化即可。
CF868F Yet Another Minimization Problem
首先发现这个东西有决策单调性。
考虑代价怎样计算。发现只有区间伸缩时可以做到 \(O(1)\) 计算,于是将其与决策单调性的分治做法相结合即可
CF1832F Zombies
题意等同于要求最大化 \(\sum |I_i\cap J_{p_i}|\)
考虑确定给 \(I\) 确定一个排序方式,使得最优方案下与 \(J_i\) 相匹配的 \(I_i\) 是一个连续区间。只按左右端点排序没有前途,考虑最大化两个区间的交集时两个区间的中点重合,所以 \(I\) 按所有区间的中点排序
朴素 DP 为 \(f_{i,j}\) 表示用 \(j\) 个区间覆盖 \(I_{[1,i]}\) 的最大价值。设 \(w(l,r)\) 为覆盖 \(I_{[l,r]}\) 的最优方案 \([L,R]\),\(L,R\) 一定和 \(I_{[l,r]}\) 的至少一个端点重合,所以 \([L,R]\) 的总数是 \(O(n)\) 级的。此时复杂度为 \(O(n^3)\),细思发现 \(w(l-1,r)\leqslant w(l,r)\leqslant w(l,r+1)\),于是就可以 \(O(n^2)\) 推出了。
DP 优化直接猜有决策单调性,即可做到 \(O(n^2\log n)\)。同时,转移点 \(h_{i,j}\) 满足 \(h_{i-1,j}\leqslant h_{i,j}\leqslant h_{i,j+1}\),所以也可 \(O(n^2)\) 递推做到(复杂度考虑斜线上总量一定)。
Slope trick(斜率维护技巧)
如果一个问题可以模拟费用流,那么它一定具有凸性
大概可以感性理解一下
考虑如下问题:
给定序列 \(a\),要求 \(b\) 单调不降,且最小化 \(\sum |a_i-b_i|\)
朴素 DP 为 \(f_{i,j}\) 表示 \(b_i=j\) 时前缀的最小代价。转移显然
这个式子看起来无法优化,实则 \(f_i\) 是个下凸壳。考虑归纳,当 \(i=1\) 时 \(f_1\) 显然是下凸的,其前缀 \(\min\) 也是下凸的,由其向 \(f_2\) 转移时,\(f_2\) 的函数即为两个下凸函数相加,由于凸函数相加仍是凸函数,所以其仍是下凸函数。
考虑用数据结构维护凸包。在这个问题中,可以直接用一个大根堆维护凸包上所有斜率拐点,由于每次斜率的变化量都是 \(+1,-1\),所以定义以 \(p\) 为左端点的线段的斜率为堆中大于等于 \(p\) 的元素的相反数。若插入的斜率变化量多于 \(1\),插入多个节点即可
CF1210G Mateusz and Escape Room
先枚举 \(n\rightarrow 1\) 的权值转移断环成链。DP 要求 \([1,i]\) 满足限制的同时需考虑 \(i\rightarrow i+1\) 的贡献,将其设计至状态中即可,转移式形如
从形式上可以看出其具有凸性。用大根堆与小根堆分别维护斜率为负/正的直线即可,插入时先分别给大小根堆打 tag 平移,再插入 \(|x|\) 、调整两个堆即可
复杂度 \(O(n^2\log n)\) 卡卡就过了 注意到答案关于 \(n\rightarrow 1\) 的权值同样具有凸性,所以与三分结合即可
[APIO2016] 烟花表演
显然可子树向上 DP 转移且转移与叶子到根的距离相关,直接列转移式子十分丑陋。将转移看作函数的叠加,之后咕咕咕
动态 DP
考虑有些 DP 可以矩阵转移,于是可以用线段树维护转移矩阵。
树上 DDP 需要结合树剖,并将重儿子的贡献与轻儿子的贡献矩阵分开计算以树剖。但这个做法复杂度为双 \(\log\)。
全局平衡二叉树
是否存在一种形似点分树的重构树结构使得树高为 \(\log\) 且可维护矩阵呢?有的兄弟,有的
将原树上的每条重链单独提出建成一棵二叉树,轻边即是两棵二叉树中向上连接的指针。然后咕咕咕
[ZJOI2022] 深搜
咕咕咕

浙公网安备 33010602011771号