斜率优化 dp 学习笔记

先来看一道例题:

P3195 [HNOI2008]玩具装箱

首先考虑普通 dp。

设 $dp[i]$ 表示 $1\sim i$ 如何划分区间可以得到最小费用。

可以得到转移方程

$$dp[i] = \min_{j = 1} ^ {i} dp[j - 1] + (i - j - L + \sum_{k = i} ^ j C_k) ^ 2$$

通过前缀和优化,原方程简化为:

$$dp[i] = \min_{j = 1} ^ {i} dp[j - 1] + (i - j - L + s[i] - s[j - 1]) ^ 2$$

这是一个极其普通的 $\Theta(n^2)$ 方程。

注意到平方式,考虑斜率优化。

设 $p[i]=s[i]+i$。

$$ \begin{aligned} dp[i] &= \min_{j = 1} ^ {i} dp[j - 1] + ((s[i] + i) - (s[j - 1] + j - 1) - (L + 1)) ^ 2 \\ &= \min_{j = 1} ^ {i} dp[j - 1] + (p[i] - p[j - 1] - (L + 1)) ^ 2 \end{aligned} $$

考虑对于两个决策点 $j_1$ 和 $j_2$,$j_2$ 优于 $j_1$,所以有

$$ dp[j_1 - 1] + (p[i] - p[j_1 - 1] - (L + 1)) ^ 2 \ge dp[j_2 - 1] + (p[i] - p[j_2 - 1] - (L + 1)) ^ 2 $$

$$ dp[j_1 - 1] + (p[i] - (p[j_1 - 1] + L + 1)) ^ 2 \ge dp[j_2 - 1] + (p[i] - (p[j_2 - 1] + L + 1)) ^ 2 $$

拆开平方式,得到

$$ dp[j_1 - 1] + p[i]^2 + (p[j_1 - 1] + L + 1)^2 - 2\times p[i]\times (p[j_1 - 1] + L + 1) \ge dp[j_2 - 1] + p[i]^2 + (p[j_2 - 1] + L + 1)^2 - 2\times p[i]\times (p[j_2 - 1] + L + 1) $$

化简得

$$ 2\times p[i]\times (p[j_2 - 1] + L + 1) - 2\times p[i]\times (p[j_1 - 1] + L + 1) \ge (dp[j_2 - 1] + (p[j_2 - 1] + L + 1)^2) - (dp[j_1 - 1] + (p[j_1 - 1] + L + 1)^2) $$

设 $q[i] = (p[i] + L + 1)^2$。

$$ 2\times p[i]\times (p[j_2 - 1] - p[j_1 - 1]) \ge (dp[j_2 - 1] + q[j_2 - 1]) - (dp[j_1 - 1] + q[j_1 - 1]) $$

$$ 2\times p[i] \ge \dfrac{(dp[j_2 - 1] + q[j_2 - 1]) - (dp[j_1 - 1] + q[j_1 - 1])}{p[j_2 - 1] - p[j_1 - 1]} $$

设 $r[i] = dp[i] + q[i]$。

$$ 2\times p[i] \ge \dfrac{r[j_2 - 1] - r[j_1 - 1]}{p[j_2 - 1] - p[j_1 - 1]} $$

实际上因为我们前面的最基础的求和式子是 $1\sim i$ 取 $\min$ 的,如果想消掉这一堆 $-1$ 把最前面的范围改成 $0\sim i-1$ 就可以了。


只要满足这个式子,那么 $j_1$ 就是比 $j_2$ 优的。

右边是一个很像求斜率的东西。

放在几何的角度上,我们重新描述一遍这个东西:

对于两个点 $J_1(p[j_1 - 1], r[j_1 - 1])$ 和 $J_2(p[j_2 - 1], r[j_2 - 1])$,如果两点确定的直线的斜率 $\dfrac{r[j_2 - 1] - r[j_1 - 1]}{p[j_2 - 1] - p[j_1 - 1]} \le 2\times p[i]$ 时,$j_1$ 是更优的决策点。

画个图。

不同颜色的线段表示这些点的斜率为正的下凸壳。

图中绿色的直线代表 $2\times p[i]$。

此时我们的最优决策点 $j$ 就是图中绿色直线最靠近的蓝色点的位置。

这边给出了一种 $\Theta(n\log n)$ 的解法:考虑维护一个单调栈,对每个点 dp 完,与凸包的维护相同,然后二分。

当然我们想要的复杂度是 $\Theta(n)$ 的。

这里借鉴了该题第一篇题解的思路:

考虑维护单调队列。

取第一个 $\dfrac{r[j_2 - 1] - r[j_1 - 1]}{p[j_2 - 1] - p[j_1 - 1]} > 2\times p[i]$ 的点,也就是 head++。操作结束得到的 head 即为最优决策。

然后算出 $dp[i]$。

这个时候要想把 $i$ 对应的点加入凸壳,就反复将队尾删去直到斜率满足条件为止。

考虑到每个点最多进一次出一次,时间复杂度 $O(n)$。

posted @   TernaKagiri  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示