[BZOJ1910][CTSC2002]颁奖典礼 DP

来源:互联网 发布:电梯破解软件 编辑:程序博客网 时间:2024/04/29 15:09

F[1,i,l,r]表示第一个矩形的下端在第i行的l到r之间,第一个矩形的最大面积。F[2,i,l,r]表示第二个矩形的下端在第i行的l到r之间,前两个矩形的最大面积。F[3,i,l,r]表示第三个矩形的下端在第i行的l到r之间,前三个矩形的最大面积。
如果l~r都是0才能开始转移。
F[1,i,l,r]=F[1,i-1,l,r]+r-l+1;
F[2,i,l,r]=max(F[2,i-1,l,r],Q[1,i-1,l,r])+r-l+1;
F[3,i,l,r]=max(F[3,i-1,l,r],Q[2,i-1,l,r])+r-l+1;
Q[1,i,l,r]表示满足lk < l,rk > r的F[1,i,lk,rk]的最大值。
Q[2,i,l,r]表示满足lk > l,rk < r的F[2,i,lk,rk]的最大值。
特别地,当max(F[k,i-1,l,r],Q[k-1,i-1,l,r])=0时,F[k,i,l,r]=0;(k=2,3)。因为转移非法。
Q可以在算完当行后处理。F,Q的第二维都可以滚动。
最后所有F[3,i,l,r]的最大值即为答案。
时间复杂度O(n^3)。
代码:

var  n,m,i,j,l,r,k,now,last,ans,o1,o2:longint;  s:array[0..210,0..210]of longint;  f:array[1..3,0..1,0..210,0..210]of longint;  q1,q2:array[0..1,0..210,0..210]of longint;function max(x,y:longint):longint;begin  if x>y then exit(x)  else exit(y);end;begin  readln(n,m);  fillchar(s,sizeof(s),0);  for i:=1 to n do    for j:=1 to m do    begin      read(s[i,j]);      inc(s[i,j],s[i,j-1]);    end;  now:=1;  last:=0;  ans:=0;  fillchar(q1,sizeof(q1),0);  fillchar(q2,sizeof(q2),0);  fillchar(f,sizeof(f),0);  for i:=1 to n do  begin    for l:=1 to m do      for r:=l to m do      begin        for k:=1 to 3 do f[k,now,l,r]:=0;        q1[now,l,r]:=0;        q2[now,l,r]:=0;        if s[i,r]-s[i,l-1]=0 then        begin          f[1,now,l,r]:=f[1,last,l,r]+r-l+1;          o1:=max(f[2,last,l,r],q1[last,l-1,r+1]);          o2:=max(f[3,last,l,r],q2[last,l+1,r-1]);          if o1>0 then f[2,now,l,r]:=o1+r-l+1;          if o2>0 then f[3,now,l,r]:=o2+r-l+1;          ans:=max(ans,f[3,now,l,r]);          q1[now,l,r]:=f[1,now,l,r];          q2[now,l,r]:=f[2,now,l,r];        end;      end;    for l:=1 to m do    begin      q1[now,l,m]:=max(q1[now,l,m],q1[now,l-1,m]);      for r:=m downto l do      begin        q1[now,l,r]:=max(q1[now,l,r],q1[now,l,r+1]);        q1[now,l,r]:=max(q1[now,l,r],q1[now,l-1,r]);      end;    end;    for l:=m downto 1 do    begin      q2[now,l,m]:=max(q2[now,l,m],q2[now,l+1,m]);      for r:=l to m do      begin        q2[now,l,r]:=max(q2[now,l,r],q2[now,l,r-1]);        q2[now,l,r]:=max(q2[now,l,r],q2[now,l+1,r]);      end;    end;    now:=now xor 1;    last:=last xor 1;  end;  writeln(ans);end.
0 0