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;
}
posted @ 2025-02-10 17:11  wwqwq  阅读(24)  评论(0)    收藏  举报