忘掉吧,我给你一个解
https://blog.csdn.net/csyifanZhang/article/details/104827171
↑更好的阅读体验

最大和子矩阵

给定一个矩阵

0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 

求出和最大的子矩阵,看到这个问题的时候,我第一时间想到的是维护二维矩阵的前缀和,然后对每个点遍历他左上方的所有矩形的前缀和,相减即为该矩阵的和,取最大值即可

#define MAX 105
#define ll int

ll sum[MAX][MAX], a[MAX][MAX];

int main() {
    ll N;
    while (cin >> N) {
        memset(sum, 0, sizeof(sum));
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= N; j++) {
                cin >> a[i][j]; sum[i][j] = sum[i][j - 1] + a[i][j];//按行求前缀数组
            }
        }
        //按行求前缀数组
        for (int j = 1; j <= N; j++)
            for (int i = 1; i <= N; i++)
                sum[i][j] = sum[i - 1][j] + sum[i][j];
        ll res = 0;
        for (int i = 0; i <= N; i++)
            for (int j = 0; j <= N; j++)
                for (int m = i; m <= N; m++)
                    for (int n = j; n <= N; n++) {
                        //如果端点在一行或者一列 那么直接前缀和之差
                        if (m == i || n == j) res = max(res, sum[m][n] - sum[i][j]);
                        //如果端点不同行也不同列
                        else  res = max(res, sum[m][n] - sum[m][j] - sum[i][n] + sum[i][j]);
                    }
        cout << res << endl;
    }
}

打眼一看复杂度,剪枝也减不了多少。,应该被卡死,当然这道题并没有卡死,但是为了这个思路我还是写了

此时,我们应该想到,一维子序列的最大和数组就是在上述搜索的过程中优化得来的,那么同样的,二维应该如何进行优化呢?可不可以对每一列,我们把它与它右边的列分别相加进行组合,比如在考虑第一列的时候,我们考虑的次序分别为1,1+2,1+2+3,1+2+3+4,如果考虑第二列,那应该考虑的次序为2,2+3,2+3+4,将这些列的组合纵向相加,看例子

0 -2 -7 0  (1):0  (1+2):-2 。。。
9 2 -6 2          9            11
-4 1 -4 1       -4            -3
-1 8 0 -2       -1             7

此时如果我们纵向求最大和子序列,对(1+2)而言,就是求(1,2)两列围成的区域内,最大和子矩阵,对(1+2)求最大和子序列,显然可以得到15,也就是正确结果。

#include<iostream>
#include<cmath>
#include<iomanip>
#include<string.h>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

#define MAX 505
#define inf 1e9
#define ll int
#define p pair<ll, ll>

ll n, a[MAX][MAX], b[MAX][MAX], res;


int main() {
    cin >> n;
    for (ll i = 1; i <= n; i++) for (ll j = 1; j <= n; j++) cin >> a[i][j];
    res = a[1][1];
    for (ll i = 1; i <= n; i++) {//从第一列开始
        memcpy(b, a, sizeof(a));
        for (ll j = i + 1; j <= n; j++) {//其后的第j列
            for (ll k = 1; k <= n; k++)
                b[k][j] += b[k][j - 1];
        }
        for (ll j = i; j <= n; j++) {//其后的第j列
            res = max(res, b[0][j]);
            for (ll k = 2; k <= n; k++) {
                if (b[k - 1][j] > 0) b[k][j] = b[k - 1][j] + b[k][j];
                res = max(res, b[k][j]);
            }
        }
    }
    cout << res << endl;
}