您的位置:首页 > 其它

[BZOJ1910][CTSC2002]颁奖典礼 DP

2017-05-01 20:45 302 查看
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
f
4000
or 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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: