大意
给出一个矩阵,上下左右相连,求最大子矩阵。
分析
相连只有上下、左右两种情况,因此我们只要将
A |
复制成
A | A |
A | A |
这样复制4份就行了。然后枚举矩形,用O(1)时间算出矩阵和。O(N^4) (个人认为不是最优,求交流)。卡常数,详见代码。
program p10827;
Const
dx:array[1..3] of longint=(0,1,1);
dy:array[1..3] of longint=(1,0,1);
Var
a:array[-1..160,-1..160] of longint;
t,f:array[-1..160] of longint;
n,tt,i,j,k,l,ans:longint;
begin
readln(tt);
while tt>0 do begin dec(tt);
readln(n);
for i:=1 to n do
begin
for j:=1 to n do
begin
read(a[i,j]);
for k:=1 to 3 do
a[i+dx[k]*n,j+dy[k]*n]:=a[i,j];
end;
readln;
end;
ans:=-maxlongint;
//枚举矩阵,O(1)求和 O(N^4)
for i:=1 to n do
for j:=1 to n do
for k:=0 to n-1 do
for l:=0 to n-1 do
begin
t[l]:=t[l-1]+a[i+k,j+l]; //Sum (i+k,j) ~ (i+k,j+l)
if k=0 then f[l]:=t[l] else inc(f[l],t[l]); //F[ (k,) l]:对于以(i,j)为左上角,(k,l)为右下角矩形之和
if f[l]>ans then ans:=f[l];
end;
writeln(ans);
end;
end.