浅谈斜率优化
DP模型
形如\(f(i)=\max \{f(j)+w(i,j)\}\quad(1\le j<i)\)的dp状态转移方程,朴素的转移时间复杂度为\(O(n^2)\),如果\(w\)中不含i,j的乘积项,并且当i固定时\(w\)具有单调性,那么我们可以用单调队列优化转移,时间复杂度为\(O(n)\)
如果\(w\)中含有i,j的乘积项,我们使用斜率优化优化状态转移
【HNOI2008】玩具装箱
根据题意,状态转移方程为\(f[i]=\min\{f[j]+(sum[i]-sum[j]+i-j-L-1)^2\}\quad(j < i)\)
这个方程是\(O(n^2)\)的,我们考虑有斜率优化
令\(a[i]=sum[i] + i,\ b[i]=sum[i]+i+L+1\)
假设\(j\)为决策点,那么
我们将这个式子看做一条直线\(y=kx+b\),其中\(y=f[j]+b[j]^2\),\(k=2a[i]\),\(x=b[j]\),\(b=f[i]-a[i]^2\)
对于每一个\(i\),这条直线的斜率确定,\(f[i]\)的转移转化为:当直线过\(P(b[j],f[j]+b[j]^2)\)时,截距加上\(a[i]^2\)
题目的答案事实上是找到最小的截距
所以,我们将上述直线从下往上平移,经过的第一个决策点就是截距最小的点
所以,可能成为决策点的P组成了一个下凸包,凸包的斜率是递增的,而且目标直线的斜率也是递增的
显然,决策点就是斜率第一个大于目标直线的点
我们用一个单调队列维护一下凸包
对于队首:如果队首前两个点的直线的斜率小于目标直线,那么直接出队
对于插入:如果即将插入的点与队尾的点的直线斜率小于队列后两个点的直线斜率,那么队尾弹出
那么我们就完成了了斜率优化
【CF1083E】 The Fair Nut and Rectangles
分析状态转移方程可知,我们要求出最大的截距,所以我们用单调队列维护一个上凸壳即可
【APIO2014】序列分割
分析状态转移方程可知,我们要求出最大的截距,并且直线的斜率是负的,凸壳位于第三象限,这样维护一个下凸壳即可