[每日一题]:最大子矩阵和
题目:
一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。
例如:3*3的矩阵:
-1 3 -1
2 -1 3
-3 1 2
和最大的子矩阵是:
3 -1
-1 3
1 2
题目链接:
https://www.51nod.com/Challenge/Problem.html#problemId=1051
最大子段和:
侃侃:
这个题是 最大子段和的 二维升级版,如何将二维的降为一维的呢?
想一下,如果我们将 所有的一行压缩成一行,那么是不是就是我们
求的最大子段和了。
分析:
预处理行和列,进行压缩,得到每一列的前缀和。
枚举行。
接下来跟求最大子段和类似,进行求即可。
Code:
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 505;
LL dp[maxn][maxn];
LL a[maxn];
int n,m;
LL value;
int main(void) {
scanf("%d%d",&m,&n);
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; j ++) {
scanf("%lld",&value);
// 预处理,进行压缩
dp[i][j] = dp[i - 1][j] + value;
}
}
LL ans = -INF;
for(int i = 1; i <= n; i ++) {
for(int j = i; j <= n; j ++) {
LL num = 0;
// 我们将几行压缩成了一行,就成了求最大子段和
for(int k = 1; k <= m; k ++) {
num += dp[j][k] - dp[i - 1][k];
if(num < 0) num = 0;
if(num > ans) ans = num;
}
}
}
cout << ans << endl;
return 0;
}
如果说年轻人未来是一场盛宴的话,那么我首先要有赴宴的资格。