问题描述
给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。
其中,A的子矩阵指在A中行和列均连续的一块。
输入格式
输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。
输出格式
输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
样例输入
3 3
-1 -4 3
3 4 -1
-5 -2 8
样例输出
10
样例说明
取最后一列,和为10。
数据规模和约定
对于50%的数据,1<=n, m<=50;
对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。
#include<iostream>
using namespace std;
int main()
{
int hang,lie,jz[501][501],f[500],dp[500],ans=-9999999;
int i,j,k,beg,end;
cin>>hang>>lie;
for(i=1;i<=hang;i++)
for(j=1;j<=lie;j++)
{
cin>>jz[i][j];
}
for(beg=1;beg<=hang;beg++) //起始行
{
for(i=1;i<=lie;i++)f[i]=0;
for(end=beg;end<=hang;end++) //终止行
{
for(k=1;k<=lie;k++) //把起始行和终止行的前k列分别加起来
{
f[k]+=jz[end][k];
}
dp[1]=f[1]; //接下来就是一维的了,参照最大子序列
if(dp[1]>ans)
ans=dp[1];
for(i=2;i<=lie;i++)
{
if(dp[i-1]<0) //前一段是负的就重新加
dp[i]=f[i];
else
dp[i]=dp[i-1]+f[i];
if(dp[i]>ans)
ans=dp[i];
}
}
}
cout<<ans;
return 0;
}