求矩阵的最大子矩阵和
比较经典的问题了,,最原始的想法应该是枚举所有子矩阵,显然不行
然后我们可以想到 O(n) 的连续字段和
然后我们用 a [ i ] [ j ] 表示第 i 列 前 j 个数的和(前缀和的方法),
然后 枚举任意两行,用 b [ k ] 表示第 k 列 当前段的 和,再对 b [ ] 求最长连续字段和
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
#include<stack>
#include<queue>
#include<algorithm>
// cout << " === " << endl;
using namespace std;
typedef long long ll;
const int maxn = 200 + 7, INF = 0x3f3f3f3f, mod = 1e9+7;
int T, n, x, max_;
int a[maxn][maxn], b[maxn];
void init() {
max_ = -INF;
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
scanf("%d", &x);
a[i][j] = a[i-1][j] + x;
}
}
}
void find_max() {
int t = 0, sum = 0;
for(int z = 1; z <= n; ++z) {
sum += b[z];
if(sum > t) t = sum;
else if(sum < 0) sum = 0;
}
max_ = max(max_, t);
}
void solve() {
for(int i = 0; i < n; ++i) {
for(int j = i+1; j <= n; ++j) {
memset(b, 0, sizeof b);
for(int k = 1; k <= n; ++k) {
b[k] = a[j][k] - a[i][k];
}
find_max();
}
}
printf("%d\n", max_);
}
int main() {
while(scanf("%d", &n) != EOF && n) {
init();
solve();
}
return 0;
}