题目大意:给出 n*n 的矩阵,找每隔数字之和最大的子矩阵,输出最大和。
解题思路:枚举矩阵左上和右下的坐标,分别合并子矩阵的每列,使得二维转化为一维,然后利用连续子序列最大和去做就行。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<string.h>
const int INF = 0x3f3f3f3f;
const int NINF = -INF -1;
using namespace std;
int val[110][110];
int sum[110];
int N;
int main() {
while (scanf("%d", &N) != EOF) {
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
scanf("%d", &val[i][j]);
int maxn = NINF;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
memset(sum, 0, sizeof(sum));
for (int k = i; k < N; k++) {
int tmp = 0;
for (int l = j; l < N; l++) {
sum[l] += val[k][l];
if (tmp < 0) {
tmp = 0;
}
tmp += sum[l];
if (tmp > maxn) {
maxn = tmp;
}
}
}
}
}
printf("%d\n", maxn);
}
return 0;
}
O(n
4
)可以过,time(ms):30
试着优化,删了一层 for,time(ms):0
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<string.h>
const int INF = 0x3f3f3f3f;
const int NINF = -INF -1;
using namespace std;
int val[110][110];
int sum[110];
int N;
int main() {
scanf("%d", &N);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
scanf("%d", &val[i][j]);
int maxn = NINF;
for (int i = 0; i < N; i++) {
memset(sum, 0, sizeof(sum));
for (int j = i; j < N; j++) {
int tmp = 0;
for (int k = 0; k < N; k++) {
sum[k] += val[j][k];
if (tmp < 0) {
tmp = 0;
}
tmp += sum[k];
if (tmp > maxn) {
maxn = tmp;
}
}
}
}
printf("%d\n", maxn);
return 0;
}