很明显我们得到朴素的转移方程
dp[i]=min{dp[j]+(i−j−1+sum[i]−sum[j]−L)2,dp[i]} (0≤j<i)
时间复杂度为
O(N2)
我们定义
f[i]=sum[i]+i,C=L+1
,那么上式转变成
dp[i]=min{dp[j]+(f[i]−f[j]−C)2,dp[i]} (0≤j<i)
然后我们来证明决策的单调性
假设在
i
处有两个决策点
即要证明
dp[j]+(f[i]−f[j]−C)2>dp[k]+(f[i]−f[k]−C)2——————[1]
假设i后面的某状态t有f[t]=f[i]+v (t>i)
我们想知道 i 对于后面状态
dp[j]+(f[t]−f[j]−C)2dp[j]+(f[i]+v−f[j]−C)2dp[j]+(f[i]−f[j]−C)2+2⋅v⋅(f[i]−f[j]−C)+v2>>>dp[k]+(f[t]−f[k]−C)2dp[k]+(f[i]+v−f[k]−C)2dp[k]+(f[i]−f[k]−C)2+2⋅v⋅(f[i]−f[k]−C)+v2
由 [1] 我们得到
(f[i]−f[j]−C)f[k]>>(f[i]−f[k]−C)f[j]
显然 f[i] 单调递增且 k>j ,那么假设 [1] 成立
dp[j]+(f[i]−f[j]−C)2>dp[k]+(f[i]−f[k]−C)2
我们将其展开可得
dp[j]+f[i]2+(f[j]+C)2−2⋅f[i]⋅(f[j]+C)dp[j]+(f[j]+C)2−dp[k]−(f[k]+C)2>>dp[k]+f[i]2+(f[k]+C)2−2⋅f[i]⋅(f[k]+C)2⋅f[i]⋅(f[j]−f[k])
dp[j]−dp[k]+(f[j]+C)2−(f[k]+C)22(f[j]−f[k])<f[i]
所以我们得到斜率 x(j,k)
x(j,k)=dp[j]−dp[k]+(f[j]+C)2−(f[k]+C)22(f[j]−f[k])
有x(j,k)<f[i]
所以当 j<k且x(j,k)<f[i] 时,我们可以 O(1) 判断 k比j更优,同时我们发现它的两个条件满足单调队列优化的性质
const
maxn=50005;
var
sum,f,t,dp,x:array[0..maxn]of int64;
q:array[0..2*maxn]of longint;
i,j,k:longint;
n,l,head,tail,tt:longint;
c:int64;
function g(a,b:longint):real;
var d:real;
begin
d:=(dp[a]-dp[b]+(f[a]+c)*(f[a]+c)-(f[b]+c)*(f[b]+c))/(2.0*(f[a]-f[b]));
exit(d);
end;
begin
readln(n,l); sum[0]:=0; c:=l+1;
for i:=1 to n do
begin
readln(x[i]);
sum[i]:=sum[i-1]+x[i];
f[i]:=sum[i]+i;
end;
q[1]:=0; dp[0]:=0; head:=1; tail:=1;
for i:=1 to n do
begin
while (head<tail)and(g(q[head],q[head+1])<=f[i]) do inc(head);
tt:=q[head];
dp[i]:=dp[tt]+(f[i]-f[tt]-c)*(f[i]-f[tt]-c);
while (head<tail)and(g(q[tail-1],q[tail])>g(q[tail],i)) do dec(tail);
inc(tail); q[tail]:=i;
end;
writeln(dp[n]);
end.