此题数据规模不大,可以通过暴力水过,代码如下
#include <iostream> using namespace std; const int maxn=101; int num[maxn][maxn]; int n; int getM() { int i,j,k,i2,j2; int f[maxn]; int max=-1<<20,sum; for(i=1;i<=n;i++) { memset(f,0,sizeof(f)); for(j=i;j<=n;j++) { for(k=1;k<=n;k++) { f[k]+=num[j][k]; } for(i2=1;i2<=n;i2++) { sum=0; for(j2=i2;j2<=n;j2++) { sum+=f[j2]; if(sum>max) max=sum; } } } } return max; } int main() { while(cin>>n) { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) cin>>num[i][j]; } int max=getM(); cout<<max<<endl; } return 0; }
可以通过dp提高效率,对于一维矩阵,设f[i]为以i为终点的最大连续段,那么可知f[i]=max(m[i],f[i-1]+m[i],即)当f[i-1]<0时,f[i]=m[i](m为此一维矩阵),当f[i-1]>0,f[i]=f[i-1]+m[i],所以最终的最大值就是f[i]中的最大值。时间效率从暴力O(n4)优化到O(n3).
#include <iostream> using namespace std; const int maxn=101; int num[maxn][maxn]; int n; int getM() { int i,j,k; int f[maxn]; int max=-1<<20,sum; for(i=1;i<=n;i++) { memset(f,0,sizeof(f)); for(j=i;j<=n;j++) { for(k=1;k<=n;k++) { f[k]+=num[j][k]; } sum=0; for(k=1;k<=n;k++) { sum=f[k]>(sum+f[k])?f[k]:(sum+f[k]); if(sum>max) max=sum; } } } return max; } int main() { while(cin>>n) { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) cin>>num[i][j]; } int max=getM(); cout<<max<<endl; } return 0; }