该题是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