「斜率优化」解析及例题
Posted qixingzhi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「斜率优化」解析及例题相关的知识,希望对你有一定的参考价值。
前言
我们知道单调队列可以用来优化动态规划,当状态转移方程可以被表示为f[i] = (只与j有关的) + 一些常数 时便可以用单调队列来保存j来O(1)完成寻找j的过程,因此将$O(n^2)$优化为了$O(n)$
那么如果当有一个转移方程变为了f[i] = (f[j] + 与i有关的)^2 ...这种情况时,我们发现展开的时候有f[j]*s[i]这类的项,因此不能再用单调队列直接来进行优化了,这时候就要用到斜率优化。
例题分析
空说没用,举例来讲吧:
传送门:>[HNOI2008]玩具装箱TOY<
题意:给你n件物品,物品i被压缩成一维以后长度为C[i]。现在你要把这些玩具按顺序放进几个一维容器中。其中制作一个长度为X的一维容器所需要的费用的是$(X-L)^2$。如果在一个一维容器中放入多个玩具,则每两个相邻的玩具之间要放进一个长度为1的东西用来隔离。想造几个容器就造几个容器。问把所有玩具装好的最小费用。数据范围$N leq 50000$
首先,很容易得出一个$O(n^2)$的转移方程$$f[i] = f[j] + (sum[i] - sum[j] + i - (j+1)-L)^2$$
整理得$$f[i] = f[j] + (sum[i]+i-(sum[j]+j)-(L+1))^2$$
设$s[k] = sum[k] + k, L = L+1$,则$$f[i] = f[j] + (s[i]-(s[j]+L))^2$$
展开得$$f[i] = f[j] + s[i]^2 - 2 * s[i] * (s[j] + L) + (s[j] + L)^2$$
移项$$f[j]+s[i]^2+(s[j]+L)^2 = 2 * s[i] * (s[j] + L) + f[i]$$
至此,我们已经将转移方程做了一些改变。由于当前考虑i,我们可以把i作为已知量,未知的是j。因此可以将有关j的作为变量来得到一个直线方程(一次函数):
$$f[j]+s[i]^2+(s[j]+L)^2 = 2 * s[i] * (s[j] + L) + f[i] Longleftrightarrow y = kx + b$$
因此,对于所有可供我们转移的j都可以看做坐标$(s[j] + L, f[j]+s[i]^2+(s[j]+L)^2)$。同时我们容易发现,斜率是一个常数,我们要求的$f[i]$是该直线的截距
所以我们的问题可以转化成这样:
给出一条已知斜率的直线,求当该直线经过其中一个点时的最小截距。
这个问题可以理解成:当一条直线从下往上平移时,碰到第一个点时的截距。
很容易发现,这个点一定是最外层的点(也就是凸包上的点)。因此我们可以维护一个下凸包,并且可以保证,下凸包内相互连接的线段的斜率依次递增。
想象一下画面,也很容易发现我们碰到的第一个点两边线段的斜率一定左边小于他,右边大于它。也就是说直线刚好顶在一个尖角上。
因此只要求出这个尖角就好了。
此时我们可以用单调队列来维护。由于直线的斜率是$2 * s[i]$,所以依次考虑i时,斜率是不断会递增的。因此所有斜率小于当前直线的线段的左端点可以全部踢掉了,因为以后他们也不会再有用了。这就好像单调队列一样。好了,此时的那个点就是我们要找的那个点了。依据状态转移方程得到f[i],并且i作为一个新的点加入点的行列。此时还是像单调队列一样考虑。看看i能否放在目前维护的凸包的最后面,并且我们需要保证的是线段的斜率依次递增。所以我们不断判断来踢出尾部的节点。踢出尾部节点的正确性也非常好证明:无论如何,由于i与结尾t的连线斜率较小,所以以后的直线肯定先碰到i再碰到t,并且i会永远存在,所以t就不必要存在了。
但是我们注意到了,在我们的y坐标中拥有$s[i]^2$,这就不仅仅与i有关了,还与i有关?其实这与i根本没有关系,因为我们在算斜率时分子是两个y坐标的差,而对于同一条直线,$s[i]^2$显然是相等的,所以他们在做差时就会被减掉从而被抵消。更一般的,所有与j不想关的都会被减掉,无论是x坐标还是y坐标。所以本题的x,y坐标可以被改成$(s[j], f[j]+(s[j]+L)^2)$
总结
现在对斜率优化动态规划的题目做一个总结,如下:
1. 依据题目,列出$O(n^2)$或更别的待优化的状态转移方程
2. 对方程进行变形成为$y = kx + b$的形式,令截距为f[i]
3. 得到x,y坐标,同时去除不与j相关的冗余项
4. 考虑得到的截距是要最大还是最小,从而维护上凸包还是下凸包
5. for循环,先踢出队头的,从而得到符合要求的进行转移,再踢出队尾的
6. 输出答案
以上是关于「斜率优化」解析及例题的主要内容,如果未能解决你的问题,请参考以下文章