http://poj.org/problem?id=1050
给100*100的矩阵 元素是任意整数
求一个子矩阵,使得其元素和最大
思路:
假设最优子矩阵的上下边界是 第i行和第j行,
那么我们只需要 把 从第i行 到第j行的元素累加起来,生成一个一维数组
然后对一维数组求个最大连续区间和就ok; O(n)
所以我们只需要枚举 i 和j O(n^2)
复杂度 O(n^3)
累加部分可以直接用前缀和预处理。。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
int n;
int i,j;
int k,h;
int max(int a,int b)
{return a<b?b:a;}
int tm[105][105];
int tmp[105];
int main()
{
int zero=0;
scanf("%d",&n);
int mark=-129;
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
{
scanf("%d",&tm[i][j]);
if (tm[i][j]>mark)
mark=tm[i][j];
if (!tm[i][j])
zero=1;
}
}
int maxx=0;
for (i=1;i<=n;i++) //以第i行为头
{
memset(tmp,0,sizeof(tmp));
for (j=i;j<=n;j++)
{
for (k=1;k<=n;k++) //把i到n行都累加起来 看作一行
{
tmp[k]+=tm[j][k];
}
int sum=0; //trick? max<0
for (k=1;k<=n;k++) //对一行求dp_max
{
if (sum+tmp[k]<0)
sum=0;
else
sum+=tmp[k];
if (sum>maxx)
maxx=sum;
}
if (sum>maxx)
maxx=sum;
}
}
if (maxx==0&&!zero) //全为负数输出最大的负数
maxx=mark;
printf("%d\n",maxx);
return 0;
}