MY*****

poj 1821 fence

朴素的也不好写:

  for i:=0 to n do
    f[i,0]:=0;
  for i:=1 to n do
    begin
      for j:=1 to a[i].s-1 do
        f[i,j]:=max(f[i-1,j],f[i,j-1]);
      for j:=a[i].s to a[i].s+a[i].l-1 do
        begin
          if j>l then break;
          f[i,j]:=max(f[i,j-1],f[i-1,j]);
          for k:=0 to a[i].s do
            if j-k<=a[i].l then
              f[i,j]:=max(f[i,j],f[i-1,k]+(j-k)*a[i].p);
          if f[i,j]>ans then ans:=f[i,j];
        end;
    end;

  

写朴素的写了有一个多小时,一开始根本没注意连续这个问题,后来有忘了a[i].s前面的值的初始化。

非常好的一个题目。

给出单调队列优化后的核心代码:

begin
  readln(l,n);
  for i:=1 to n do
    with a[i] do
      readln(l,p,s);
  qs(1,n);
  for i:=1 to n do
    begin
      for j:=0 to a[i].s-1 do f[i,j]:=f[i-1,j];
      head:=1; tail:=1; w[1]:=-1; q[1]:=0;
      for j:=max(0,a[i].s-a[i].l) to a[i].s-1 do
        begin
          k:=f[i-1,j]-a[i].p*j;
          while (head<=tail)and(w[tail]<=k) do dec(tail);
          inc(tail);
          w[tail]:=k;
          q[tail]:=j;
        end;
      for j:=a[i].s to l do
        begin
          while (head<=tail)and(q[head]<j-a[i].l) do inc(head);
          f[i,j]:=max(f[i-1,j],f[i,j-1]);
          if head<=tail then f[i,j]:=max(f[i,j],w[head]+a[i].p*j);
        end;
    end;
  writeln(f[n,l]);
end.

  

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

导航