巧克力
Time Limit:4000MS Memory Limit:65536K
Description
布欧可以把人变成巧克力吃了来增加他的能量,也有可能减少。
现在布欧变了n*m个巧克力,并把巧克力排成一个n*m的矩形,现在布欧想选择一个子矩形,把这个子矩形吃了来增加他的能量,可他不知道选哪个才能使他的能量增加值p最大,布欧也可以选择一个都不吃,这样p = 0。
现在布欧要你告诉他p的最大值,不然他就先把你变成巧克力吃了!
Input
第一行:一个整数T 代表测试个数,
接着T组测试数据。
对每组测试数据:
第一行:n m 两个整数
接着n行每行m个空格隔开的整数a(i,j)代表对应巧克力的能量值(注意可以是负数,吃了能量减少)
1<=n,m<=300
-1000<= a(i,j) <= 1000
Output
T行
每行一个整数 p
Sample Input
3
3 3
1 -1 4
2 -2 3
3 -10 1
3 3
-1 -1 -1
-1 -1 -1
-1 -1 -1
3 3
1 1 -10
-1 1 -10
1 1 -10
///
本题题意就是求最大子矩阵之和,这是一天模板题。就是把找最大子矩阵化成一维序列找最大的子段。
#include<iostream>
#include<cstring>
using namespace std;
int a[333][333];
int b[333][333];
int main()
{ //freopen("cho.in","r",stdin);
//freopen("haha.txt","w",stdout);
int T;
while(cin>>T)
{
while(T--)
{
memset(b,0,sizeof(b));
int n,m;
int sum=0;
int leap=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(i==1) b[i][j]=a[i][j];
if(i!=1) b[i][j]=b[i-1][j]+a[i][j];//记录第j列 从1到i行的 列的和
}
for(int i=1;i<=n;i++)//取第i行
for(int j=i;j<=n;j++)//取第j行
{ int leap=0;
for(int h=1;h<=m;h++)
{
leap+=(b[j][h]-b[i-1][h]);
if(leap>sum) {sum=leap;}
if(leap<0) {leap=0;}//转换成一维数组来求最大值
}
}
cout<<sum<<endl;
}
}
return 0;
}