题目大意:对应矩阵的值为矩阵中所有元素的和, 要求所给出的矩阵中, 和最大的子矩阵,输出最大和。
解题思路:可以看成是求若干次连续序列最大和,第一次求1行,第二次就是1 和2 行对应元素的和的数组,第三次就是1 、 2 和3 行、、、、、、然后知道1 加到n行, 就换2行, 然后是2 + 3 行,以此类推。
注意最大值的初始化不可以是0, 有负数的可能。
#include <stdio.h>
#include <string.h>
const int N = 105;
const int Min = -2147483645;
int maxsum(int A[], int x, int y) {
if (y - x == 1) return A[x];
int cur = x + (y - x) / 2;
int a = maxsum(A, x, cur), b = maxsum(A, cur, y);
int Max = a > b ? a : b;
int v = 0, L = A[cur - 1], R = A[cur];
for (int i = cur - 1; i >= x; i--) {
v += A[i];
L = v > L ? v : L;
}
v = 0;
for (int i = cur; i < y; i++) {
v += A[i];
R = v > R ? v : R;
}
return Max > R + L ? Max : R + L;
}
int num[N][N], sum[N];
int main() {
int n, Max, total;
while (scanf("%d", &n) == 1) {
// Init;
Max = Min;
memset(num, 0, sizeof(num));
// Read;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &num[i][j]);
// Count;
for (int i = 0; i < n; i++) {
memset(sum, 0, sizeof(sum));
for (int j = i; j < n; j++) {
for (int k = 0; k < n; k++)
sum[k] += num[j][k];
total = maxsum(sum, 0, n);
if (total > Max)
Max = total;
}
}
// Printf;
printf("%d\n", Max);
}
return 0;
}