对斜率优化的一些个人理解
详细讲解可以去看 这篇,讲的很好,不过太长了(划掉),这里仅文字简要描述斜率优化。
斜率优化主要用来处理一类 dp 问题,形如 \(f_i = k_j\times x+b_j\)。
首先我们要知道什么情况下 \(z\) 比 \(j\) 转移过来更优。
假设求最小值,求最大值同理的,那么求最小值就是要求 \(k_z\times x+b_z < k_j\times x+b_j\),同时假设 \(k_z > k_j\)
移项后就是 \(x < \frac{b_j-b_z}{k_z-k_j}\),改一下就是 \(x > \frac{b_z-b_j}{k_z-k_j}\)。
具体问题根据符号不同划出来也会有点小差别,不过影响不大。
这个很有用,之后在求答案时会用到,先记着。
然后我们考虑维护一个下凸包,容易发现非下凸包的点一定不会成为最优转移点。
这个比较容易,但还是说一下原因吧。
在不确定 \(x\) 的情况下,设这三个点分别是 \(x1,y1\)、\(x2,y2\)、\(x3,y3\),并且第一个和第三个是下凸包的点,第二个在它们中间,同时是非下凸包点。
注意到 \(x > 0\) 时,第三个点下标最大,加的值就少,同时初值也最小,所以最优。
否则若 \(x < 0\),那么第一个点下标比第二个小,同时初值也比第二个小,一定优与第二个。
那我们有了一个下凸包了,怎么求答案呢?
还记得前面说的吗,由于下凸包斜率单调递增,我们二分找到最后一个斜率不满足 \(x > \frac{b_z-b_j}{k_z-k_j}\) 的,那么这条线的左端点就是我们要的最优决策点。
显然只用看下凸包上相邻两个点的斜率即可,这是因为如果 \(a\) 优于 \(b\),\(b\) 优与 \(c\),有传递性 \(a\) 优与 \(c\)。
如果 \(x\) 是单调递增的,由于 \(x\) 单调递增那么前面不优的点后面一定不优,单调队列可以直接弹出队头,所以就是 \(O(n)\) 的。
具体的一些东西还需要根据题目来搞,不过一般的需要注意纵坐标相同的时候,此时斜率为 inf,需要根据题目删去下面的点或者上面的点。
浙公网安备 33010602011771号