解决这个的思路很简单,我文笔不是很好,希望可以表述清楚:
1.首先,我们来看一维的数组的最大子段:
例如 int a[]={0 4 -3 2},sum[i]表示以a[i]结尾的串的最大和,很容易可表示出来:sum[i]=max{(sum[i-1]+a[i]),a[i]},最后求出sum数组的最大值即为该数组的最大子段和。
2.然后进行二维扩展:例如二维矩阵A[4][4]
假如最大子矩阵的行为i~j行,则将i~j的各列加到sum数组中,即sum[k]=A[i][k]+A[i+1][k]+……+A[j][k],然后对sum数组求出最大子段即可(用第一种方法)
下面就是遍历所有的i,j组合(0,0)(0,1)……(3,2)(3,3),然后在所有的最大子段求出最大值。
#include<memory.h>
#include<stdio.h>
# define MAXN 100
int n;
int data[MAXN][MAXN];
int dp(int i,int j)
{
int p,q;
int dtmp[MAXN];
memset(dtmp,0,sizeof(dtmp));
int sum[MAXN];
int max=-127*n;
for(int p=0;p<n;p++)
{
for(q=i;q<=j;q++)
dtmp[p]+=data[q][p];
}
sum[0]=dtmp[0];
for(p=1;p<n;p++)
{
if(sum[p-1]>0)
sum[p]=sum[p-1]+dtmp[p];
else
sum[p]=dtmp[p];
}
for(p=0;p<n;p++)
if(sum[p]>max)
max=sum[p];
return max;
}
int main()
{
int i,j;
int temp;
scanf("%d",&n);
int max=-127;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&data[i][j]);
}
}
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
temp=dp(i,j);
if(max<temp)
max=temp;
}
}
printf("%d",max);
return 0;
}