MY*****

poj 3709 K-Anonymous Sequence

终于把最后一道优化DP的题目做了,斜率优化之前掌握的不是非常熟练呀。

朴素方程:f[i]=min{f[k]+s[i]-s[k]-a[k+1]*(i-k)}。

就这么一个朴素方程的化简,搞了很久。

把减号写成加号导致化简完全错误,纠结于直接用double还是用int64的x和y,后来有纠结于≤和≥的问题。这才完全搞定斜率优化。不错的题目。

代码:

var
  q,f,s,a:array[0..500002] of int64;
  head,tail,n,m,i,j,t:longint;
  k,xx,yy,zz:int64;

function y(k,j:longint):int64;
begin
  exit(f[k]-f[j]+s[j]-s[k]-a[j+1]*j+a[k+1]*k);
end;

function x(k,j:longint):int64;
begin
  exit(a[k+1]-a[j+1]);
end;

begin
  readln(t);
  while t>0 do
    begin
      dec(t);
      readln(n,m);
      for i:=1 to n do
        begin
          read(a[i]);
          s[i]:=s[i-1]+a[i];
        end;
      f[0]:=0;
      head:=0;
      tail:=0;
      q[0]:=0;
      for i:=1 to n do
        begin
          while (head<tail)and(y(q[head],q[head+1])>=i*x(q[head],q[head+1]))
          do inc(head);
          k:=q[head];
          f[i]:=f[k]+s[i]-s[k]-a[k+1]*(i-k);
          if i>=2*m-1 then
            begin
              zz:=i-m+1;
              while head<tail do
                begin
                  xx:=q[tail-1];
                  yy:=q[tail];
                  if y(xx,yy)*x(yy,zz)>=(y(yy,zz)*x(xx,yy)) then dec(tail)
                  else break;
                end;
              inc(tail);
              q[tail]:=zz;
            end;
         end;
      writeln(f[n]);
    end;
end.

  

posted on 2011-10-20 07:49  reflec94  阅读(254)  评论(0编辑  收藏  举报

导航