浅谈斜率优化

本文深入探讨DP模型的状态转移方程优化方法,包括单调队列和斜率优化的应用,通过具体题目解析,如【HNOI2008】玩具装箱、【CF1083E】TheFairNutandRectangles及【APIO2014】序列分割,展示如何将时间复杂度从O(n^2)优化至O(n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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\)为决策点,那么
\[ f[i]=f[j]+(a[i] - b[j])^2 \\ f[i]=f[j]+a[i]^2+b[j]^2-2\times a[i]\times b[j]\\ f[j]+b[j]^2=2\times a[i]\times b[j]+f[i]-a[i]^2 \]
我们将这个式子看做一条直线\(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】序列分割

分析状态转移方程可知,我们要求出最大的截距,并且直线的斜率是负的,凸壳位于第三象限,这样维护一个下凸壳即可

转载于:https://www.cnblogs.com/shl-blog/p/11628306.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值