该题是poj的1050号题:http://poj.org/problem?id=1050
同时在《编程之美》 2.15 小节
思想是:
1、把二维降到一维,把 同一列的若干个数的和算出来,
然后从行的角度,变成求一维数组的子数组和的最大值,
一共要计算 (1+n)*n/2 次一维数组的和最大值
2、在求同一列的若干数的和的时候,用辅助数组加快计算:
把第l列中, 第1~k行数的和提前计算好,放到辅助数组 b[k][l]中,
然后求 第l列的 第i行和第j行之间的数的和,就等于 b[i][l]-b[j-1][l]
为了计算方便,第0行、0列都不存实际数,初始化为0。
#include <iostream>
using namespace std;
int a[101][101];
int b[101][101];
int MAX = -128;
int max_two (int x, int y) {
return x>y ? x : y;
}
int main () {
int n;
cin >> n;
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
cin >> a[i][j];
}
}
for(int i=0; i<=n; i++) {
b[0][i] = 0;
}
for(int l=1; l<=n; l++) {
for(int i=1; i<=n; i++) {
b[i][l] = 0;
for(int j=1; j<=i; j++) {
b[i][l] += a[j][l];
}
}
}
for (int i=1; i<=n; i++) {
for (int j=i; j>=1; j--) {
int all = b[i][n] - b[j-1][n];
int start = all;
for (int k=n-1; k>=1; k--) {
start = max_two(b[i][k]-b[j-1][k],
start+b[i][k]-b[j-1][k]);
all = max_two(all, start);
}
MAX = max_two(MAX, all);
}
}
cout << MAX << endl;
}原文地址:http://tianyanshentong.blog.51cto.com/3356396/1560853