二维数组的最大连续和问题,核心思想就是转化为一维数组,一个所要求的矩形,有一下几个元素构成,起始行,结束行,起始列,结束列,枚举起始行和结束行,linesum[i]保存的是从起始行到结束行间第i列的和。最内层的for循环就是以为数组连续最大和的求法(不断更新最大值)。
第二段代码是动规,感觉在理解了第一种方法后再理解这段代码就很容易了,
dp[k]=max(dp[k-1]+rowsum[k],rowsum[k]);
这个是利用已经保存的状态量来更新新的状态量。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int num[101][101],linesum[101];
int main()
{
//freopen("in.txt","r",stdin);
int n,maxsum,temp;
while(scanf("%d",&n)!=EOF&&n)
{
maxsum=-2147483647;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
scanf("%d",&num[i][j]);
for(int i=0;i<n;i++)//起始行
{
memset(linesum,0,sizeof(linesum));
for(int j=i;j<n;j++)//结束行
{
for(int k=0;k<n;k++)
linesum[k]+=num[j][k];
temp=linesum[0];
for(int h=1;h<n;h++)
{
if(temp<0)
temp=0;
temp+=linesum[h];
maxsum=max(temp,maxsum);
}
}
}
cout<<maxsum<<endl;
}
return 0;
}
#include<cstdio> #include<iostream> #include<cstring> using namespace std; int num[102][102],rowsum[110],maxsum,n; void ddp(int start) { int dp[110]; memset(dp,0,sizeof(dp)); for(int j=start; j<=n; j++) //for(int j=start;j>=1;j--) { for(int k=1; k<=n; k++) { rowsum[k]+=num[j][k]; dp[k]=max(dp[k-1]+rowsum[k],rowsum[k]); maxsum=max(dp[k],maxsum); } } } int main() { //freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n) { maxsum=-2147483647; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) scanf("%d",&num[i][j]); } for(int i=1; i<=n; i++) { memset(rowsum,0,sizeof(rowsum)); ddp(i); } cout<<maxsum<<endl; } return 0; }