蓝桥杯 PREV-26 最大子阵(二维最大子序列和)

题目链接:

PREV-26 最大子阵

思路:

首先我们需要学会求一维最大子序列和(这里就不多赘述啦)
此题我们枚举这个子矩阵的上底和下底即原矩阵的两行,对于原矩阵的每一列我们都用前缀和数组记录下来;
假设现在枚举第r和第rr行,我们设立数组v(下标从1m),v[i]的值即为原矩阵a[r][i] + a[r + 1][i] + ... + a[rr][i],此时我们只需求一维数组v的最大子序列和即可;
时间复杂度 O ( m n 2 ) O(mn^2) ,但是常数不大,可以AC

代码:

#include<bits/stdc++.h>

using namespace std;

const int maxn = 505;
int n, m, a[505][505], sum[505][505];

int main() {
#ifdef MyTest
	freopen("Sakura.txt", "r", stdin);	
#endif
	scanf("%d %d", &n, &m);
	int ans = -5005;
	for(int i = 1; i <= n; ++i)
	for(int j = 1; j <= m; ++j)
	{ scanf("%d", &a[i][j]); ans = max(ans, a[i][j]); }
	if(ans <= 0) { cout << ans; exit(0); }
	for(int j = 1; j <= m; ++j)
	for(int i = 1; i <= n; ++i)
		sum[i][j] = (i ? sum[i - 1][j] : 0) + a[i][j];
	for(int r = 1; r <= n; ++r)
	for(int rr = r; rr <= n; ++rr) {
		vector<int> v(m + 1);
		for(int j = 1; j <= m; ++j) v[j] = sum[rr][j] - sum[r - 1][j];
		int rcd = 0;
		for(int i = 1; i <= m; i++) {
			if(rcd < 0) rcd = 0;
			rcd += v[i];
			ans = max(ans, rcd);
		}
	}
	cout << ans;
	return 0;
}
发布了356 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45228537/article/details/104461844
今日推荐