如果暴力做,要枚举每个子矩阵的一条对角线上的两个点,几乎有n^2 * n^2的复杂度。如果把行数变为1,那就是最大子段和的问题,所以当把几行都加起来成一行,再求最大子段和,就可以知道这几行内的最优解……
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 110
int a[maxn][maxn],tmp[maxn],n;
int max(int x,int y){return x>y?x:y;}
int getMax() //求最大子段和
{
int ans,pre;
ans=pre=0;
for(int i=0;i<n;i++)
{
if(pre<=0) pre=tmp[i];
else pre+=tmp[i];
ans=max(ans,pre);
}
return ans;
}
int main()
{
while(cin>>n)
{
for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>a[i][j];
int ans=0;
for(int i=0;i<n;i++)
{
memset(tmp,0,sizeof(tmp));
for(int j=i;j<n;j++)
{
for(int k=0;k<n;k++) tmp[k]+=a[j][k]; //此处在枚举列,进行行数的叠加
ans=max(ans,getMax());
}
}
cout<<ans<<endl;
}
return 0;
}