简单的思路
求出所有以[i,j]为右下端点的所有矩阵大小,并比较其最值。时间复杂度N^4
dp
对于[i,j],显然的其所有矩阵是[i+1,j]的子矩阵,多出的部分是第i行的前j个元素。那么我们就可以通过[i,j]求出[i+1,j]
关于求矩阵大小,可以先累加每行,再将行和累加;同样的,先算列和再累加也是一样的。
令sums[i][j][k]为以[i-k]到[i, j]的求和(列和),那么根据上述两条,可以得到递推公式sums[i][j][k] = (k == 0) ? mat[i][j] : sums[i-1][j][k-1] + mat[i][j];此时,求sums[i][j][k]的最大累加和,即求得该点所有矩阵的最大值。

#include<iostream>
using namespace std;
const int MAXN = 105;
int n;
int dp[MAXN];
int sums[MAXN][MAXN][MAXN];    //i行j列高为k(k+1)的矩阵和
int getMax(int arr[MAXN], int n){//dp
    int res = dp[0] = arr[0];
    for(int i = 1; i < n; ++i){
        dp[i] = max(dp[i-1], 0) + arr[i];
        res = max(res, dp[i]);
    }
    return res;
}
int main(){
    int val;
    int ans = 0x80000000;    //INT_MIN
    cin >> n;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            cin >> val;
            for(int k = 0; k <= i; ++k)
                if(k == 0)//这一行
                    sums[i][k][j] = val;
                else
                    sums[i][k][j] = sums[i-1][k-1][j] + val;
        }
    }
    for(int i = 0; i < n; ++i)
        for(int k = 0; k <= i; ++k)
            ans = max(ans, getMax(sums[i][k], n));
    cout << ans;
    
    return 0;
}