斜率优化——apio2010特别行动队

这是我写的第二个斜率优化。。。

有了更深的认识

发现斜率优化很神奇,加一个斜率和单调队列就可以了

发现是斜率优化重点是找到f[i]=min(max){f[j]+w[j,k]}这样一个DP方程,然后试着对决策j优于k列式子讨论,作数学变形。发现有一边是dp[]之差比定值[j] [k]之差就是斜率。

还有要注意斜率可以用slop算出来,这样程序更清晰,条件也比较好看

program tt;
var i,n,a,b,c,xx,l,r:longint;
    f:array[0..1000000]of int64;
    s:array[0..1000000]of int64;
    q:array[0..1000000]of longint;
function slop(x,y:longint):double;
begin
 slop:=(f[x]-f[y]+a*s[x]*s[x]-a*s[y]*s[y]+b*s[y]-b*s[x])/(2*a*(s[x]-s[y]));
end;
begin
 read(n);
 read(a,b,c);
 s[0]:=0;
 for i:=1 to n do
  begin
   read(xx);
   s[i]:=s[i-1]+xx;
  end;
 l:=1;r:=1;q[1]:=0;f[0]:=0;
 for i:=1 to n do
  begin
   while (l<r) and (slop(q[l],q[l+1])<s[i]) do l:=l+1;
   f[i]:=f[q[l]]+a*sqr(s[i]-s[q[l]])+b*(s[i]-s[q[l]])+c;
   while (l<r) and (slop(q[r],i)<slop(q[r-1],q[r])) do
    r:=r-1;
   r:=r+1;
   q[r]:=i;
  end;
 writeln(f[n]);
end.


你可能感兴趣的:(斜率优化——apio2010特别行动队)