dp优化小结

决策单调性优化dp

很早之前看李煜东蓝书的时候被吓到了,现在来补一下。

  • 前置芝士

决策单调性前提最优化dp。通俗地讲就是每个状态只能由一个最优地状态转移而来。

决策单调性:状态的最优转移点单调,形式化地说就是。

四边形不等式:有函数 \(w(x,y)\),令 \(a\le b \le c \le d\),若其满足 \(w(a,c)+w(b,d)\le w(a,d)+w(b,c)\) 则称函数 \(w(x,y)\) 满足四边形不等式。

决策单调性与四边形不等式的关系:考虑形如 \(dp(i)=\min\left\{dp(j)+w(j,i)\right\}\) 的dp,若 \(w(j,i)\) 满足四边形不等式,则此dp满足决策单调性。

那么我们怎么通过决策单调性优化dp呢,这有很多种方式。

  • 分治优化决策单调性dp

前提1:二维dp,且只有前一层向后一层转换,同一层之间不会转换,一般也可以使用线段树等数据结构优化。

前提2:同一层内满足决策单调性。

满足这两个条件之后就可以进行分治了。

\(l,r\) 为分治的边界,\(mid\)\(l,r\) 中点,则我们可以先转移 \(mid\)

\(L,R\) 为决策候选区间的边界,我们在转移 \(mid\) 之后可以得到一个最优转移点 \(p\)

那么不难证明 \([l,mid-1]\) 的最优决策点在 \([L,p]\) 之间,\([mid+1,r]\) 的最优决策点在 \([p,R]\) 之间。

就可以分治了,总决策区间长度为 \(O(n\log n)\) ,总候选区间长度为 \(O(n\log n)\) ,总时间复杂度为 \(O(n\log n)\)

例题:

CF833B The Bakery

这道题中还使用了一个小技巧,在计算 \(w(i,j)\) 函数的时候,使用类似于莫队的双指针维护,观察所覆盖的区间范围,不难发现移动次数为 \(O(候选区间长度)\) ,因而时间复杂度为 \(O(n\log n)\)

[POI2011]Lightning Conductor

比较板,但似乎有线性做法?

  • 二分队列优化决策单调性dp

优化形如 \(f_i=\min\limits^{i-1}_{j=0/1} \left\{f_j +w(i,j)\right\}\) 的dp方程。

根据决策单调性的定义,一个点的最优决策区间是不断右移的,只会被后面的区间反超。

那么为我们维护一个单调队列,队列中的点大小关系递减,所包含区间递增,我们更新时取队头即可。

那么如何维护这个单调队列呢,想象我们到了位置 \(i\) ,那么从队尾开始,如果有一个点决策区间的左边界不如用 \(i\) 更优,那么根据定义,这个点绝不可能比 \(i\) 更优,因此弹出。

如果有点的决策区间一部分比 \(i\) 优,一部分不比 \(i\) 优,那么简单,把比 \(i\) 优的区间设为新区间即可。

例题

[NOI2009] 诗人小G 十分甚至九分地板。

  • 二分栈优化决策单调性(?)dp

与上文的二分队列优化相反,每一种决策只会被更前面的决策所反超,因此不是传统意义上的决策单调性。

咕咕咕/

  • 包含单调优化区间dp

部分内容摘自 OI Wiki

一般情况下区间dp形如 \(f_{l,r}=\min\limits^{r-1}_{k=l}\left\{f_{l,k}+f_{k+1,r} \right\}+w(l,r)\)

前提1\(w(l,r)\) 满足区间包含单调性,即对于任意 \(l\le l^{'}\le r^{'} \le r\),满足 \(w(l^{'},r^{'})\le w(l,r)\)

前提2\(w(l,r)\) 满足四边形不等式。

若满足两个前提,则 \(f_{l,r}\) 满足四边形不等式。

性质:若 \(f_{l,r}\) 满足四边形不等式,令 \(g_{l,r}\)\(f_{l,r}\) 的最优转移点,则 \(g_{l,r-1}\le g_{l,r}\le g_{l+1,r}\)

在区间dp的同时记录最优转移点,则对于每一长度的转移点枚举时间复杂度为 \(O(n)\) ,总时间负杂度为 \(O(n^2)\)

例题

SP18637 LAWRENCE

比较特殊,只需要计算 \([1,i]\) 区间的dp值即可,但依旧可以套用上述结论,不同的是后半部分不能使用了,但这个整体又满足普通的决策单调性,另一半取 \(\le g_{i+1,j}\) 即可。

斜率优化dp

斜率优化有很多理解方法,这里所记述的是其中一种普遍使用的。

斜率优化一般又来优化形如 \(dp_i=\max\left\{ dp_j +(a_i-b_j)^2\right\}\) 的 dp 式子。

我们令:

\[dp_j +(a_i-b_j)^2 \ge dp_k +(a_i-b_k)^2 \]

拆开得到:

\[\frac{dp_j+b_j^2-(dp_k+b_k^2)}{b_j-b_k}\ge 2a_i \]

\(i\) 固定时,若 \(j,k\) 满足这个条件,则 \(j\) 一定比 \(k\) 更优。

将其投射到二维平面上,将其抽象为两个点,那么当 \(j,k\) 间斜率大于 \(2a_i\) 时,就说明 \(j\) 更优。

在大多数题目中,给出的斜率都是单调的,我们可以用单调队列维护斜率,就相当于维护一个凸包。

对队首的限制就是上式,队尾的限制就是斜率递增,每次弹出队首即可。

例题[CEOI2004] 锯木厂选址[ZJOI2007] 仓库建设[HNOI2008]玩具装箱

进阶:当给出的斜率不递增时,应该怎么办?

实际上,我们依旧可以维护一个凸包,不过不同于单调队列,维护一整个凸包。

这个可以通过平衡树/李超树/cdq分治实现,但是对于NOIP用处不大,不多赘述。

WQS 二分

通过二分斜率来优化 dp 过程的一种方法,又称 dp 凸优化。

使用WQS二分的前提:dp 图像斜率递增,即是一个凸包。

具体的说,我们把 \((i,dp_i)\) 的图像绘制出来,如果形如一个凸包,则成立。

一般的,直接求解这种 \(dp\) 的复杂度是很高的,无法接受,例如我们要求出 \(dp_k\) ,而每个一个 \(dp\) 数组所需的时间为 \(O(n)\),则总时间复杂度为 \(O(nk)\)

考虑利用凸包的性质进行优化,即我们二分一个斜率,求出这根直线与凸包的切点的坐标(同时包括横纵坐标),不难发现这对 \(k\) 是单调的。

这样当我们切到横坐标为 \(k\) 的点时,得到的即为答案。

由于每一次所需的时间仍未 \(O(n)\),因此总的时间复杂度为 \(O(n\log k)\)

一般当我们求解的问题,斜率都可以抽象为个数等具体的数值,为整数,不需要考虑精度,考虑精度的话要注意上下界和题目要求吻合。

WQS 二分的经典应用:求解恰好选择 \(k\) 个的问题,一般有这种要么是反演要么是WQS二分。

注意点:在绝大多数的情况下,WQS 二分的辅助 DP 过程中,必须要求出选几个时最优,才能调整二分上下界。

特殊情况:三点共线

有一些特定情况下,斜率不严格单调递增,因此我们有一定概率得不到自己想要的答案,这个时候很简单,只需要根据题目要求(最大/最小),选择左右端点即可。

例题:

P4383 [八省联考 2018] 林克卡特树

很有意思的题目,是和树形dp结合,我们考虑最朴素的dp方程,然后感性证明关于 k 是一个凸包,套用wqs二分即可,从这道题上也可以看出,WQS二分的应用是极为广泛和灵活的。

P5308 [COCI2018-2019#4] Akvizna

考虑朴素dp,不论是正着来还是倒着来都是可以的,不难发现可以斜率优化,可以做到 \(O(n k)\)

然后经典的恰好 \(k\) 个,上 WQS 二分,时间复杂度 \(O(n\log k)\),注意卡一下精度。

posted @ 2024-12-17 22:43  lxg_swrz  阅读(107)  评论(0)    收藏  举报