AtCoder [ABC175E] Picking Goods 题解
原文发布时间:2024-08-15 11:13。
动态规划题。
考虑设置状态,\(f_{i,j,l}\) 表示在第 \(i\) 行,第 \(j\) 列,当前行取 \(l\) 个物品能取到的价值的最大值。
接下来考虑状态转移:
考虑第 \(i\) 行,第 \(j\) 列的物品拿还是不拿。
若拿,则 \(f_{i,j,l}=\max(f_{i,j,l},f_{i,j-1,l-1}+w_{i,j})\),\(f_{i,j,1}=\max(f_{i,j,1},f_{i-1,j,p}+w_{i,j})(p \in [0,3])\)。其中 \(w_{i,j}\) 为该格子内的物品价值。
若不拿,则 \(f_{i,j,l}=\max(f_{i,j,l},f_{i,j-1,l})\),\(f_{i,j,0}=\max(f_{i,j,0},f_{i-1,j,p})(p \in [0,3])\)。
最终答案即为 \(\max(f_{r,c,0},f_{r,c,1},f_{r,c,2},f_{r,c,3})\)。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int w[3005][3005];
int f[3005][3005][5];
signed main() {
int r, c, k;
cin >> r >> c >> k;
for (int i = 1; i <= k; i++) {
int x, y, z;
cin >> x >> y >> z;
w[x][y] = z;//将物品价值转移到格子上,方便调用
}
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
for (int l = 0; l <= 3; l++) {
if (w[i][j] != 0 && l != 0) {//拿
f[i][j][l] = max(f[i][j][l], f[i][j - 1][l - 1] + w[i][j]);
f[i][j][1] = max(f[i][j][1], f[i - 1][j][0] + w[i][j]);
f[i][j][1] = max(f[i][j][1], f[i - 1][j][1] + w[i][j]);
f[i][j][1] = max(f[i][j][1], f[i - 1][j][2] + w[i][j]);
f[i][j][1] = max(f[i][j][1], f[i - 1][j][3] + w[i][j]);
}
//不拿
f[i][j][0] = max(f[i][j][0], f[i - 1][j][0]);
f[i][j][0] = max(f[i][j][0], f[i - 1][j][1]);
f[i][j][0] = max(f[i][j][0], f[i - 1][j][2]);
f[i][j][0] = max(f[i][j][0], f[i - 1][j][3]);
f[i][j][l] = max(f[i][j][l], f[i][j - 1][l]);
}
}
}
cout << max(max(f[r][c][0], f[r][c][1]), max(f[r][c][2], f[r][c][3])) << endl;
return 0;
}

浙公网安备 33010602011771号