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

这道题其实是一维上的最大子串的一个推广。如果对于一个数列,要求他的最大子串(定义与本题类似)

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

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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值