[BZOJ1010][HNOI2008]玩具装箱toy 斜率优化第一题

很明显我们得到朴素的转移方程 dp[i]=min{dp[j]+(ij1+sum[i]sum[j]L)2,dp[i]}  (0j<i)
时间复杂度为 O(N2)
我们定义 f[i]=sum[i]+i,C=L+1 ,那么上式转变成 dp[i]=min{dp[j]+(f[i]f[j]C)2,dp[i]}  (0j<i)
然后我们来证明决策的单调性
假设在 i 处有两个决策点 j,k(j<k) ,且 k 的决策比 j
即要证明

dp[j]+(f[i]f[j]C)2>dp[k]+(f[i]f[k]C)2[1]

itf[t]=f[i]+v  (t>i)
我们想知道 i 对于后面状态 t 的影响,那么要证明
dp[j]+(f[t]f[j]C)2dp[j]+(f[i]+vf[j]C)2dp[j]+(f[i]f[j]C)2+2v(f[i]f[j]C)+v2>>>dp[k]+(f[t]f[k]C)2dp[k]+(f[i]+vf[k]C)2dp[k]+(f[i]f[k]C)2+2v(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)22f[i](f[j]+C)dp[j]+(f[j]+C)2dp[k](f[k]+C)2>>dp[k]+f[i]2+(f[k]+C)22f[i](f[k]+C)2f[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<kx(j,k)<f[i] 时,我们可以 O(1) 判断 kj,

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 (headand(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 (headand(g(q[tail-1],q[tail])>g(q[tail],i)) do dec(tail);
   inc(tail); q[tail]:=i;
  end;
 writeln(dp[n]);
end.

你可能感兴趣的:(动态规划—优化—斜率优化)