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.

 

你可能感兴趣的:(ZOJ)