好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:
题目描述
原题来自:HNOI 2008
P 教授要去看奥运,但是他舍不得他的玩具,于是他决定把所有的玩具运到北京。
他使用自己的压缩器进行压缩。这个压缩器可以将任意物品变成一维,再放到一种特殊的一维容器中。P 教授有编号为 1…N 的 N 件玩具,玩具经过压缩后会变成一维,第 i 件玩具压缩后长度为 Ci。
为了方便整理,P 教授要求:
- 在一个一维容器中,玩具的编号是连续的;
- 如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物。形式地说,如果要将 i 号玩具到 j 号玩具 (i≤j) 放到同一个容器中,则容器长度不小于:x=j−i+k=i∑jCk
注意:j−i 就是填充物总长度(有 j−i 个间隔,每个间隔长度 1)。
制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为 x,其制作费用为 (x−L)2,其中 L 是一个常量。
P 教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过 L。试求最小费用。
输入格式
第一行输入两个整数 N,L;
接下来 N 行,每行一个整数 Ci。
输出格式
输出一个整数,表示最小费用。
样例
样例输入
5 4
3
4
2
1
4
样例输出
1
样例解释
N=5,L=4,玩具长度 [3,4,2,1,4]。
设前缀和 Si=∑k=1iCk,则容器 [i,j] 的长度为 $(j-i) + (S_j - S_{i-1}) = (S_j + j) - (S_{i-1} + i - 1)$。
记 Ai=Si+i,则容器 [i,j] 长度 =Aj−Ai−1,费用为 (Aj−Ai−1−L)2。
DP 方程:
$$dp[i] = \min_{0 \le j < i} \{ dp[j] + (A_i - A_j - 1 - L)^2 \}$$
(注意:Ai−1 对应 Aj 时 j=i−1,但更准确的是 dp[i] 表示前 i 个玩具的最小费用,且最后一个容器以 i 结尾,转移时枚举上一个容器的结尾 j,则容器为 [j+1,i],其长度为 Ai−Aj,费用为 (Ai−Aj−L)2,因为 j 到 i 有 i−j 个玩具,间隔数为 i−j−1?不对,应该用 Ai=Si+i,这样 $A_i - A_j = (S_i + i) - (S_j + j) = (S_i - S_j) + (i - j)$,正好是玩具总长加上 i−j 个间隔(i−j 个玩具之间有 i−j 个间隔?实际上 i−j 个玩具之间有 i−j−1 个间隔,但公式 i−j 正确吗?让我们验证:容器 [j+1,i] 有 i−j 个玩具,间隔数为 i−j−1,总长度 = (Si−Sj)+(i−j−1)。
但 $A_i - A_j = (S_i + i) - (S_j + j) = (S_i - S_j) + (i-j)$,多了一个 1,所以实际长度应为 Ai−Aj−1。
因此费用为 (Ai−Aj−1−L)2。
经计算,最优分组:
容器1:玩具1,2,3 → 长度 3+4+2+2=11(玩具3个,间隔2个),费用 (11−4)2=49
容器2:玩具4,5 → 长度 1+4+1=6,费用 (6−4)2=4
总费用 53,不是 1。
显然不对,样例输出是 1,说明我的公式有误。
实际上标准写法:设 sum[i]=∑k=1iCk,则容器 [i,j] 的长度为:
x=sum[j]−sum[i−1]+(j−i)
即玩具总长加上 j−i 个间隔(j−i+1 个玩具,有 j−i 个间隔)。
费用为 (x−L)2=(sum[j]−sum[i−1]+j−i−L)2。
令 a[i]=sum[i]+i,则 x=a[j]−a[i−1]−1?再检查:
$$a[j] - a[i-1] = (sum[j] + j) - (sum[i-1] + i-1) = (sum[j] - sum[i-1]) + (j - i + 1)$$
而我们要的 x=(sum[j]−sum[i−1])+(j−i),所以 x=a[j]−a[i−1]−1。
因此费用为 (a[j]−a[i−1]−1−L)2。
令 b[i]=a[i]+L+1,则费用为 (a[j]−b[i−1])2。
转移方程:
$$dp[i] = \min_{0 \le j < i} \{ dp[j] + (a[i] - b[j])^2 \}$$
其中 a[i]=sum[i]+i,b[j]=sum[j]+j+L+1。
样例计算后可得最小费用 1。
数据范围
对于全部数据:
- 1≤N≤5×104
- 1≤L,Ci≤107
时空限制
- 时间:1000 ms
- 内存:524288 KB
提示
此题为 斜率优化 DP 经典题。
DP 方程:
$$dp[i] = \min_{0 \le j < i} \{ dp[j] + (a[i] - b[j])^2 \}$$
其中 a[i]=Si+i,b[j]=Sj+j+L+1,Si 是 Ci 的前缀和。
展开:
$$dp[i] = \min_{0 \le j < i} \{ dp[j] + b[j]^2 - 2a[i]b[j] \} + a[i]^2$$
设 Y[j]=dp[j]+b[j]2,X[j]=b[j],则:
$$dp[i] = \min_{0 \le j < i} \{ Y[j] - 2a[i]X[j] \} + a[i]^2$$
斜率优化:
对于 j1<j2,决策 j2 优于 j1 的条件为:
X[j2]−X[j1]Y[j2]−Y[j1]≤2a[i]
由于 a[i] 单调递增(Ci>0),X[j] 单调递增(b[j] 单调递增),因此可以用单调队列维护下凸包,队首为最优决策。
步骤:
- 计算前缀和 Si,并计算 a[i], b[i];
- 初始化队列,将 j=0 入队(dp[0]=0,X[0]=b[0]=L+1,Y[0]=(L+1)2);
- 遍历 i 从 1 到 N:
- 若队首两点斜率 ≤2a[i],则弹出队首;
- 取队首 j 计算 dp[i];
- 将 (X[i],Y[i]) 加入队尾,维护凸包(弹出队尾上凸点);
- 输出 dp[N]。
复杂度 O(N)。