# Candy糖果盒

Description

Input

Output

1 ≤ n，m ≤ 1000
0 ≤ a [ i ][ j ]≤ 255

Sample Input

输出最大糖果数

Sample Output

3 4
1  2  3  4
5  0  6  3
10 3  4  0

Hint

17

（这题是原题的加强版）

这个题目是: 给你一个矩阵,要求你找一个子矩阵,使得子矩阵内不包含，并且矩阵内元素之和最大.

首先下一个定义,有效矩形: 内部不包含0元素的矩形. 极大子矩形: 4个边界都不能向外扩展的有效矩形. 由于,因此最大子矩形一定是极大子矩形

 var

ans,high,right,left,i,j,k,t,s,n,m:longint;

sum,a,l,r,h:array[-10..1000,-10..1000] of longint;

function min(p,q:longint):longint;

begin

if p>q then exit(q); exit(p);

end;

begin

for i:=1 to n do

begin

for j:=1 to m do

begin

sum[i,j]:=sum[i,j-1]+sum[i-1,j]-sum[i-1,j-1]+a[i,j];

end;

end;

for i:=1 to n do    //L[i,j]代表(i,j)这个点向左伸展的长度为多少

begin

for j:=1 to m do

if a[i,j]=0 then

l[i,j]:=0

else

l[i,j]:=l[i,j-1]+1;

for j:=m downto 1 do  //R[i,j]代表(i,j)这个点向右伸展的长度为多少

if a[i,j]=0 then

r[i,j]:=0

else r[i,j]:=r[i,j+1]+1;

end;

for i:=1 to n do      //H[i,j]代表(i,j)这个点向上伸展的长度为多少

for j:=1 to m do

if a[i,j]<>0 then

if a[i-1,j]=0 then

h[i,j]:=1

else

begin

h[i,j]:=h[i-1,j]+1;

l[i,j]:=min(l[i-1,j],l[i,j]);//此时L代表以(i,j)为右下角的那个矩形向左伸展的长度

r[i,j]:=min(r[i-1,j],r[i,j]);////此时R代表以(i,j)为右下角的那个矩形向右伸展的长度

end;

for i:=1 to  n do

for j:=1 to m do

begin

left:=j-l[i,j]+1;

right:=j+r[i,j]-1;

high:=i-h[i,j]+1;

if ans<sum[i,right]-sum[high-1,right]-sum[i,left-1]+sum[high-1,left-1]  then

ans:=sum[i,right]-sum[high-1,right]-sum[i,left-1]+sum[high-1,left-1] ;

end;

writeln(ans);

end.
View Code

var
sum,l,r,ll,rr,h,a:array[0..1000,0..1000] of longint;
x,y,z,m,ans,max,i,j,k,n:longint;
function min(x,y:longint):longint;
begin
if x<y then
exit(x)
else exit(y);
end;
begin
for i:=1 to n do
for j:=1 to m do
for i:=0 to n do
for j:=0 to m do
sum[i,j]:=sum[i-1,j]+sum[i,j-1]-sum[i-1,j-1]+a[i,j];
for i:=1 to n do
begin
for j:=1 to m do
if a[i,j]<>0 then
l[i,j]:=l[i,j-1]+1;
for j:=m downto 1 do
if a[i,j]<>0 then
r[i,j]:=r[i,j+1]+1;
for j:=1 to m do
if a[i,j]<>0 then
begin
h[i,j]:=h[i-1,j]+1;
if a[i-1,j]=0 then
begin
ll[i,j]:=l[i,j];
rr[i,j]:=r[i,j];
end   else
begin
ll[i,j]:=min(l[i,j],ll[i-1,j]);
rr[i,j]:=min(r[i,j],rr[i-1,j]);
end;
end;
end;
for i:=1 to n do
for j:=1 to m do
if a[i,j]<>0 then
begin
x:=i-h[i,j]+1;
y:=j-ll[i,j]+1;
z:=j+rr[i,j]-1;
ans:=sum[i,z]+sum[x-1,y-1]-sum[i,y-1]-sum[x-1,z];
if ans>max then max:=ans;
end;
writeln(max);
end.
View Code

posted @ 2016-12-05 15:03  jkl~  阅读(308)  评论(0编辑  收藏  举报