糖果盒 ( Candy Box )
问题描述:
一个被分为 n*m 个格子的糖果盒,第 i行第 j 列位置的格子里面有 a [ i ][ j ]颗糖。本来 tenshi 打算送这盒糖果给某 PPMM的,但是就在要送出糖果盒的前一天晚上,一只极其可恶的老鼠夜袭糖果盒,有部分格子被洗劫并且穿了洞。tenshi必须尽快从这个糖果盒里面切割出一个矩形糖果盒,新的糖果盒不能有洞,并且 tenshi希望保留在新糖果盒内的糖的总数尽量多。
任 务 :
请帮tenshi设计一个程序计算一下新糖果盒最多能够保留多少糖果。
输入格式:
从文件CANDY.INP读入数据。第一行有两个整数 n、m。第 i + 1行的第 j 个数表示 a [ i ][ j ],如果这个数为 0,则表示这个位置的格子被洗劫过。其中:
1 ≤ n,m≤ 300
0 ≤a [ i ][ j ]≤ 255
输出格式:
输出最大糖果数到 CANDY.OUT。
样例
CANDY.INP | CANDY.OUT |
3 4 1 2 3 4 5 0 6 3 10 3 4 0 | 17 |
==================================
最优子矩阵问题
将4维转3维
记录个数组
======================
{
ID:jie19952
PROG:
LANG:PASCAL
}
var
n,m:longint;
map,f:array[0..1000,0..1000]of longint;
sum:array[0..1000,0..1000]of longint;
procedure init;
begin
assign(input,'candy.in');
assign(output,'candy.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure main;
var
i,j,k:longint;
now:longint;
ans:longint;
begin
readln(n,m);
fillchar(map,sizeof(map),0);
fillchar(f,sizeof(f),0);
for i:=1 to n do
for j:=1 to m do
begin
read(map[i,j]);
if map[i,j]=0 then map[i,j]:=-100000;
end;
fillchar(sum,sizeof(sum),0);
for i:=1 to m do
for j:=1 to n do
sum[i,j]:=sum[i,j-1]+map[j,i];
ans:=0;
for i:=1 to n do
for j:=i to n do
begin
now:=0;
for k:=1 to m do
begin
if now+sum[k,j]-sum[k,i-1]<sum[k,j]-sum[k,i-1] then
now:=sum[k,j]-sum[k,i-1]
else now:=now+sum[k,j]-sum[k,i-1];
if ans<now then ans:=now;
end;
end;
writeln(ans);
end;
begin
init;
main;
terminate;
end.