#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; }
有问题欢迎留言