此题数据规模不大,可以通过暴力水过,代码如下
#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;
}