题目链接:P3195 [HNOI2008] 玩具装箱 - 洛谷。
本题是经典 DP 斜率优化题型。
题目描述
P 教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。
P 教授有编号为 的 件玩具,第 件玩具经过压缩后的一维长度为 。
为了方便整理,P 教授要求:
- 在一个一维容器中的玩具编号是连续的。
- 同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物。形式地说,如果将第 件玩具到第 个玩具放到一个容器中,那么容器的长度将为 。
制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为 ,其制作费用为 。其中 是一个常量。P 教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过 。但他希望所有容器的总费用最小。
输入格式
第一行有两个整数,用一个空格隔开,分别代表 和 。
第 到 第 行,每行一个整数,第 行的整数代表第 件玩具的长度 。
输出格式
输出一行一个整数,代表所有容器的总费用最小是多少。
输入输出样例 #1
输入 #1
输出 #1
说明/提示
对于全部的测试点,,,。
题解
参考文档:斜率优化 - OI Wiki
状态定义和转移
定义 为前 个物品收纳的最小费用。
边界条件:
状态转移方程:
其中, 表示将区间 装到同一个容器的代价。
其中, 表示 的前缀和。
最终答案即为 。
该解法的时间复杂度为 ,无法通过本题。
DP 斜率优化
状态转移方程可转化为:
其中,。
将与 无关的项移到等式左边:
使用线性规划的思路来处理方程:考虑一次函数的斜截式 ,将其移项得到 。我们将与 有关的信息表示为 的形式,把同时与 有关的信息表示为 ,把要最小化的信息(与 有关的信息)表示为 ,也就是截距。具体地,令
则转移方程就写作 。我们把 看作二维平面上的点,则 表示直线斜率, 表示一条过 的斜率为 的直线的截距。问题转化为:选择合适的 (),最小化直线的截距。

如图,我们将这个斜率为 的直线从下往上平移,直到有一个点 在这条直线上,则有 ,这时 取到最小值。算完 后,我们就把 这个点加入点集中,以做为新的 DP 决策。那么,我们该如何维护点集?
容易发现,可能让 取到最小值的点一定在下凸壳上。因此在寻找 的时候我们不需要枚举所有 个点,只需要考虑凸包上的点。而在本题中 随 的增加而递增,因此我们可以单调队列维护凸包。
具体地,设 表示过 和 的直线的斜率。考虑队列 ,维护的是下凸壳上的点。显然下凸壳上的斜率 是单增的,即,对于 ,始终有 成立。
我们维护一个指针 来计算 最小值。我们需要找到一个 的 (特别地,当 或者 时要特别判断),这时就有 ,即 是 的最优决策点。由于 是单调递增的,因此 的移动次数是均摊 的。
在插入一个点 时,我们要判断是否 ,如果不等式不成立就将 弹出,直到等式满足。然后将 插入到 队尾。
这样我们就将 DP 的复杂度优化到了 。