您的位置:首页 > 其它

POJ-1050-To the Max-dp

2015-11-10 15:55 351 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: