main
黄海 2 years ago
parent c34d152f21
commit 39794eb57e

@ -5,6 +5,7 @@ int n;
int a[N][N]; // 存储题目中的矩阵
int s[N][N]; // 二维前缀和
// O(N^4)算法
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {

@ -1,26 +1,31 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 130;
int a[N][N], s[N][N];
const int N = 330;
int n;
int a[N][N], dp[N];
int res = INT_MIN;
int main() {
int n, res = INT_MIN;
cin >> n;
for (int i = 1; i <= n; i++)
// 前缀和(竖直方向)
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
s[i][j] = s[i - 1][j] + a[i][j]; // 利用一维前缀和把当前第j列前面的1~j-1列的值累加和压缩到第j列每列都是如此处理
a[i][j] += a[i - 1][j];
}
// O(N^3)算法
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) { // 前缀和需要下标从0开始
int sum = 0;
}
// 降维变成一维dp
for (int i = 0; i <= n - 1; i++) {
for (int j = i + 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
sum = max(sum, 0) + s[i][k] - s[j][k];
res = max(res, sum);
dp[k] = max(a[j][k] - a[i][k], dp[k - 1] + a[j][k] - a[i][k]);
res = max(res, dp[k]);
}
}
}
cout << res << endl;
cout << res;
return 0;
}

@ -274,7 +274,41 @@ signed main() {
#### [$P1719$ 最大加权矩阵](https://www.luogu.com.cn/problem/P1719)
**解题思路**
**$O(N^4)$算法**
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 130;
int n;
int a[N][N]; // 存储题目中的矩阵
int s[N][N]; // 二维前缀和
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
}
int mx = INT_MIN; // 存储答案
// 遍历左上角坐标,与,右下角坐标
for (int x1 = 1; x1 <= n; x1++) {
for (int y1 = 1; y1 <= n; y1++) {
for (int x2 = 1; x2 <= n; x2++)
for (int y2 = 1; y2 <= n; y2++) {
if (x2 < x1 || y2 < y1) continue; //
mx = max(mx, s[x2][y2] + s[x1 - 1][y1 - 1] - s[x2][y1 - 1] - s[x1 - 1][y2]); // 求最大值
}
}
}
cout << mx << endl; //
return 0;
}
```
**$O(N^3)$算法**
这道题和$P1115$最大子段和思路类似。
只是将一维升到二维,很重要的解决思路:**矩阵压缩**。
如果能把二维降到一维,那就好处理了。

Loading…
Cancel
Save