题目链接:http://poj.org/problem?id=1050
这是求最大子矩阵的一个问题,对于这个题,首先我们要知道怎么求一维最大子序列和。给你一个数组a,求其中连续一段a[i]+a[i+1]+……+a[j]最大:
ans=-inf,sum=0
for i=1->n
if(sum>0)sum+=a[i]
else sum=a[i]
ans=max(ans,sum)
那么,二维的就是压缩成一维的求,如果我告诉你这个矩阵从第i行到第j行,但是不知道从几列到几列,那么不就是把第i行到第j行的每一列加起来,作为一个元素,形成一个数组,然后按上面的代码来吗?那么问题就是枚举任意两行了,见代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int N,a[105][105],ans;
int main()
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
{
scanf("%d",&a[i][j]);
a[i][j]+=a[i-1][j];//a[i][j]代表j列元素的前i项和
}
ans=-128;
for(int i=1;i<=N;i++)//上界
{
for(int j=i;j<=N;j++)//下界
{
int sum=0;//上下压缩成一行,求最大子序列和
for(int k=1;k<=N;k++)
{
int now=a[j][k]-a[i-1][k];//i行到j行第k列元素被压缩成一个
if(sum>0)sum+=now;
else sum=now;
ans=max(ans,sum);
}
}
}
printf("%d",ans);
return 0;
}