您的位置:首页 > 其它

poj 1050 To the max(二维最大子串和,最大子矩阵)

2018-02-01 15:59 232 查看
这道题其实是一维上的最大子串的一个推广。如果对于一个数列,要求他的最大子串(定义与本题类似)

那么一维的时候有两种类似的做法。

1.一维的时候,就是要找一个l,r 让前缀和sum[r]-sum[l-1]最大,然后从左往右扫的时候,扫到i的时候 用一个min存sum[j]
(j=1,2,...,i-1)的最小值 然后sum[i]-min就是以i为右端点的区间的最大值,然后用sum[i]更新min。

即f[i]=sum[i]-min;min=min(min,sum[i]);

2.如果只求一维里面某一段的最大值的话,可以以0为界. 
如果前缀和小于0,就把和改为0然后加上当前这个位置的值作为和

即f[i]=max(f[i-1],0)+sum[i];

二维的时候,则还要拓展一下,用i,j去枚举列上的左右边界,然后用一个k从第一行开始从上往下扫,这样的话就可以覆盖每一个子矩阵。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int map[105][105];
int main()
{
int n, i, j, k, maxn = -(1 << 30),t;
cin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++) {
cin >> t;
map[i][j] += map[i][j - 1] + t;//记录每一行的前缀和,方便后续操作
}
for(i=1;i<=n;i++)
for (j = i; j <= n; j++) {//i,j是枚举列的边界
int he = 0;
for (k = 1; k <= n; k++) {//k从第一行开始往下,如果扫到的he小于0,那么以i,j为边界,第k行为下界的子矩阵最大值就是本行的值
if (he < 0)he = 0;//否则的话本行的最大值就应该是前面的和加上本行的值
he += map[k][j] - map[k][i - 1];
maxn = max(maxn, he);
}
}
cout << maxn << endl;

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