#include <iostream>
#include <vector>
using namespace std;
// 和大部分不大一样的思路,可以看看。
// 首先同样是枚举这个矩阵的每个点
// 我们有两个dp存储,dph[i][j][h]表示以a[i][j]为矩阵的最右下角,高度为h的最大矩阵值
// dpw[i][j][h]表示以a[i][j]为矩阵的最右下角,宽度为w的最大矩阵值
// 有状态转移方程
// dpw[i][j][w] = max(dpw[i - 1][j][w] + fen, fen)和dph[i][j][h] = max(dph[i][j - 1][h] + fen, fen)
// 以dpw来解释,其中fen表示从a[i][j - w + 1]到a[i][j]的总和
// 因此以a[i][j]为矩阵的最右下角,宽度为w的最大矩阵值就是fen加上以a[i - 1][j]为矩阵的最右下角,宽度为w的最大矩阵值或者fen
// dph的解释同理
void solve() {
int n;
cin >> n;
vector<vector<int>> a(n + 1, vector<int>(n + 1)), b(n + 1, vector<int>(n + 1));
vector<vector<vector<int>>> dph(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1))),
dpw(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1)));
for(int i = 1; i <= n ; i++)
for(int j = 1; j <= n ; j++) {
cin >> a[i][j];
b[i][j] = b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1] + a[i][j];
// b表示二维前缀和
}
int ans = -0x3f3f3f3f;
for(int i = 1; i <= n ; i++)
for(int j = 1; j <= n ; j++) {
int res = -0x3f3f3f3f;
for(int w = 1; w <= j ; w++) {
int x = i, y = j - w + 1;
int fen = b[i][j] - b[x - 1][j] - b[i][y - 1] + b[x - 1][y - 1];
dpw[i][j][w] = max(dpw[i - 1][j][w] + fen, fen);
res = max(res, dpw[i][j][w]);
}
for(int h = 1; h <= i ; h++) {
int x = i - h + 1, y = j;
int fen = b[i][j] - b[x - 1][j] - b[i][y - 1] + b[x - 1][y - 1];
dph[i][j][h] = max(dph[i][j - 1][h] + fen, fen);
res = max(res, dph[i][j][h]);
}
ans = max(ans, res);
}
cout << ans;
}
int main() {
solve();
return 0;
}
有问题欢迎留言

京公网安备 11010502036488号