- 0711测试
T2
- 2024-7-11 20:32:44 @
/*
f[i][j] = 第i天以j结尾的最大值
取第i行的(j-k+1,j)
取第i+1行的(j-k+1,j)
f[i][j] =
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int f[2][N], pre[N], nxt[N];
vector<int>a[N];
int n, m, k;
int Get(int l, int r, int id) {
if (l > r)
return 0;
return a[id][r] - a[id][l - 1];
}
int main() {
cin >> m >> n >> k;
for (int i = 1; i <= n; i++) {
a[i].push_back(0);
for (int j = 1; j <= m; j++) {
int x;
cin >> x;
a[i].push_back(x);
a[i][j] += a[i][j - 1];
}
}
//先算第一行
for (int i = 1; i <= m; i++) {
f[1][i] = Get(max(i - k + 1, 1), i, 1);
}
if (n > 1) {
//算第二行
for (int i = 1; i <= m; i++) {
f[1][i] += Get(max(i - k + 1, 1), i, 2);
}
//pre
for (int i = 1; i <= m; i++) {
pre[i] = max(pre[i - 1], f[1][i]);
}
//nxt
for (int i = m; i >= 1; i--) {
nxt[i] = max(nxt[i + 1], f[1][i]);
}
}
for (int i = 2; i <= n; i++) {
int pos1 = i % 2;
int pos2 = pos1 ^ 1;
for (int j = 1; j <= m; j++) {
f[pos1][j] = Get(max(1, j - k + 1), j, i);
//如果上一行取得数在前面,不重合
f[pos1][j] = max(f[pos1][j], pre[max(0, j - k)] + Get(max(1, j - k + 1), j, i));
//如果上一行取的数在后面,不重合
f[pos1][j] = max(f[pos1][j], nxt[min(j + k, m + 1)] + Get(max(1, j - k + 1), j, i));
//重叠部分
for (int t = j - 1; t >= max(1, j - k + 1); t--) {
f[pos1][j] = max(f[pos1][j], f[pos2][t] + Get(t + 1, j, i));
}
for (int t = j + 1; t <= min(m, j + k - 1); t++) {
f[pos1][j] = max(f[pos1][j], f[pos2][t] + Get(max(1, j - k + 1), max(0, t - k), i));
}
}
if (i != n) {
for (int j = 1; j <= m; j++)
f[pos1][j] += Get(max(1, j - k + 1), j, i + 1);
for (int j = 1; j <= m; j++)
pre[j] = max(pre[j - 1], f[pos1][j]);
for (int j = m; j >= 1; j--)
nxt[j] = max(nxt[j + 1], f[pos1][j]);
}
}
int pos1 = n % 2, res = 0;
for (int i = 1; i <= m; i++) {
res = max(res, f[pos1][i]);
}
cout << res << endl;
return 0;
}
0 comments
No comments so far...