斜率优化 学习笔记

发布时间 2023-03-29 10:34:43作者: xx019

0x00 前言

对于形如 \(f_i=f_j+\text{val}(i,j)\) 的递推式,斜率优化适用于 \(\text{val}(i,j)\) 中存在同时与 i,j 相关的项的情况。

0x01 引入

例题:P3195 [HNOI2008]玩具装箱

有 n 个玩具,第 \(i\) 个玩具价值为 \(c_i\) 。要求将这 n 个玩具排成一排,分成若干段。对于一段 \([l,r]\) ,它的代价为 \((r-l+\sum\limits_{i=l}^rc_i-L)^2\) ,其中 L 是一个常量,求分段的最小代价。 \(1\le n\le5\times10^4,1\le L,c_i\le10^7\)

定义 \(f_i\) 表示对前 i 个分段的最小代价,有转移 \(f_i=\min\limits_{j=0}^{i-1}(f_j+(i-(j+1)+a_i-a_j-L)^2)\) ,初始为 \(f_0=0\) 。其中 \(a_i\) 表示 \(\sum\limits_{j=1}^ic_j\) 。时间复杂度 \(\text{O}(n^2)\)

因为 \(\text{val}(i,j)\) 拆项后出现了同时与 \(i,j\) 相关的项,无法对 \(f_j+\text{val}(i,j)\) 分组后使用单调队列优化。

0x02 优化

先化简一下式子。令 \(s_i=a_i+i,L\leftarrow L+1\),则 \(f_i=f_j+(s_i-s_j-L)^2,f_i-(s_i-L)^2=(f_j+s_j^2)-2(s_i-L)s_j\)

考虑一次函数的表达式 \(y=kx+b\) ,变形为 \(b=y-kx\) 。把只与 \(i\) 有关的,只与 \(j\) 有关的和与 \(i,j\) 都有关的部分表示成 \(b,y,kx\)。即 \(b_i=f_i-(s_i-L)^2,y_i=f_j+s_j^2,k_i=2(s_i-L),x_i=s_j\) ,最小化 \(b\) 。把 \((x_i,y_i)\) 看做平面直角坐标系上的点,问题就转化成了有一条斜率为 \(k_i\) 的直线,选择合适的点 \((x_j,y_j)\) 穿过,最小化截距。

显然可能成为最优点的集合一定构成下凸壳(读者自证不难),所以维护候选转移只需要维护凸包。

0x03 实现

可以发现此题切点左侧直线斜率都小于 \(k_i\),右侧都大于 \(k_i\),且此题中 \(k_i\) 具有单调性,故可以使用单调队列维护。时间复杂度 \(\text{O}(n)\)

\(k_i\) 没有单调性,需要维护整个凸包,二分查询转移位置。时间复杂度 \(\text{O}(n\log n)\)

\(x_i,k_i\) 同时没有单调性,需要使用 CDQ/平衡树动态维护凸包,时间复杂度 \(\text{O}(n\log^2 n)\)。不过这种情况下我们一般更倾向于使用短小精悍的李超线段树。

0x04 应用

初级部分(一般的方程,直线单调)

BZOJ1597 [Usaco2008 Mar]土地购买

BZOJ1911 [Apio2010]特别行动队

BZOJ1010 [HNOI2008]玩具装箱

BZOJ1096 [ZJOI2007]仓库建设

BZOJ3437 小P的牧场

BZOJ3156 防御准备

BZOJ3675 [Apio2014]序列分割

BZOJ4518 [Sdoi2016]征途

HDU3507 Print Article

CF311B Cats Transport

高级部分(维护凸包需要二分/CDQ分治/平衡树)

BZOJ3672 [NOI2014]购票

BZOJ2726 [SDOI2012]任务安排

BZOJ1492 [NOI2007]货币兑换Cash

BZOJ3963 [WF2011]MachineWorks

BZOJ4700 适者

BZOJ2149 拆迁队

CF1083E The Fair Nut and Rectangles

0x05 总结

二分/CDQ/平衡树等能够优化 DP 方程的计算,于一定程度上降低复杂度,但不能改变这个方程本身。DP 方程的性质会取决于数据的特征,但 DP 方程本身取决于题目中的数学模型。

斜率优化 DP 需要灵活运用,其宗旨是将最优化问题转化为二维平面上与凸包有关的截距最值问题。遇到性质不太好的方程,有时需要辅以数据结构来加以解决,届时还请就题而论。