DP 优化
今天模拟赛考到了斜率优化,我发现去年暑假听得一知半解的知识点现在要彻底搞懂了。
本文我学到哪写到哪。
决策单调性优化
有些状态 \(a\) 比 \(b\) 总是要好(譬如花费更低而收益更高),那么 \(b\) 状态可以丢掉。
斜率优化
参考资料:https://oi-wiki.org/dp/opt/slope
P3195 [HNOI2008] 玩具装箱
题意
有 \(n\) 个玩具,第 \(i\) 个玩具价值为 \(c_i\) 。要求将这 \(n\) 个玩具排成一排,分成若干段。对于一段 \([l,r]\) ,它的代价为 \((r-l+\sum_{i=l}^r c_i-L)^2\) 。其中 \(L\) 是一个常量,求分段的最小代价。
\(1\le n\le 5\times 10^4, 1\le L, c_i\le 10^7\) 。
朴素 DP
\(dp_i\) 表示考虑到第 \(i\) 个物品,分若干段的最小代价。
容易推出:
前缀和优化
为了简化式子,构造函数 \(S_i=pre_i+i\),并设 \(L'=L+1\)
这个样子已经基本可以确定是斜率优化了。但是我们进一步化简:
斜率优化
我们要把转移方程转化成一次函数斜截式的形式。\(\mathcal{OIwiki}\) 是这样说的:
考虑一次函数的斜截式 \(y=kx+b\) ,将其移项得到 \(b=y-kx\) 。我们将与 \(j\) 有关的信息表示为 \(y\) 的形式,把同时与 \(i,j\) 有关的信息表示为 \(kx\) ,把要最小化的信息(与 \(i\) 有关的信息)表示为 \(b\) ,也就是截距。
设
原方程表示为
接下来,我们考虑几何意义。
图片来源于 \(\mathcal{OIwiki}。\)
发现要求截距最小。所以我们要找到合适的 \(j\)。
我们每对一个 \(i\) 求出最优转移点 \((x_j,y_j)\),先算出 \(dp_i\),然后将求出的新点 \((x_i,y_i)\) 放入坐标系。
存在性质:
- 只有下凸壳的点可能作为转移点。
- \(S_i\) 随 \(i\) 单调递增,\(k_i\) 随 \(i\) 单调递增。
由性质得,可以用单调队列维护下凸壳(凸包上的转移点位置存在单调性)。
剩下的不必多说,这里偷懒放下 \(\mathcal{OIwiki}\) 的解释。
将初始状态入队。
每次使用一条和 \(i\) 相关的直线 \(f(i)\) 去切维护的凸包,找到最优决策,更新 \(dp_i\) 。
加入状态 \(dp_i\) 。如果一个状态(即凸包上的一个点)在 \(dp_i\) 加入后不再是凸包上的点,需要在 \(dp_i\) 加入前将其剔除。

浙公网安备 33010602011771号