bzoj 3039 悬线法求最大01子矩阵

首先预处理每个F点左右,下一共有多少个F点,然后

对于每个为0的点(R),从这个点开始,一直到这个点

下面第一个R点,这一区间中的min(左),min(右)更新答案。

ps:我估计这道题数据有的格式不对,开始过不去,后来改了读入

就能过了

/**************************************************************
    Problem: 3039
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:808 ms
    Memory:17252 kb
****************************************************************/
 
//By BLADEVIL
var
    n, m                        :longint;
    map                         :array[0..1010,0..1010] of longint;
    ans, len1, len, len2        :longint;
    left, right, down           :array[0..1010,0..1010] of longint;
     
function max(a,b:longint):longint;
begin
    if a>b then max:=a else max:=b;
end;
 
function min(a,b:longint):longint;
begin
    if a>b then min:=b else min:=a;
end;
     
procedure init;
var
    i, j, k                     :longint;
    ss                          :ansistring;
begin
    readln(n,m);
    for i:=1 to n do
    begin
        readln(ss);
        k:=0;
        for j:=1 to length(ss) do
            if ss[j]<>' ' then
            begin
                inc(k);
                if ss[j]='F' then map[i,k]:=1 else map[i,k]:=0;
            end;
    end;
     
    for i:=1 to n do
        for j:=1 to m do
            if map[i,j]=0 then left[i,j]:=0 else left[i,j]:=left[i,j-1]+1;
             
    for i:=n downto 1 do
        for j:=m downto 1 do
        begin
            if map[i,j]=0 then down[i,j]:=0 else down[i,j]:=down[i+1,j]+1;
            if map[i,j]=0 then right[i,j]:=0 else right[i,j]:=right[i,j+1]+1;
        end;
     
end;
 
procedure main;
var
    i, j, k                     :longint;
begin
    for i:=0 to n do
        for j:=1 to m do
            if map[i,j]=0 then
            begin
                len:=0;
                len1:=maxlongint div 10;
                len2:=maxlongint div 10;
                for k:=1 to down[i+1,j] do
                begin
                    len1:=min(len1,left[i+k,j]);
                    len2:=min(len2,right[i+k,j]);
                    ans:=max(ans,(len1+len2-1)*k);
                end;
                if len1>=maxlongint div 10 then continue;
                inc(len,len1);
                ans:=max(ans,(len-1)*down[i+1,j]);
            end;
    writeln(ans*3);
end;
 
begin
    init;
    main;
end.

 

posted on 2013-12-29 01:46  BLADEVIL  阅读(272)  评论(0编辑  收藏  举报