寒假集训做题分享(2)

[ABC015D] 高橋くんの苦悩


知识点:二维费用背包。

根据翻译可知,这道题其实基本上就是一道二维背包的板子题,这里简单介绍一下二维费用背包。

首先,对于背包问题,我们必然是要用 \(dp\) 解决的。

定义状态

dp[i][j][k]

表示用前 \(i\) 件物品装入所能承受的最大重量为 \(j\) ,容积为
\(k\) 的背包的最大价值。

对于所有的背包问题,我们都有选与不选两种情况。

如果不选第 \(i\) 件物品,那么,就有

dp[i][j][k]=dp[i-1][j][k]

如果选择第 \(i\) 件物品,那么,由于第 \(i\) 件物品的重量为 \(a[ i ]\) ,体积为 1,所以

dp[i][j][k]=dp[i-1][j-a[i]][k-1]+b[i]

两者取最大值,就有

dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-a[i]][k-1]+b[i])

但是,这里的三维数组实际上是可以省掉一维的,所以,最终的状态转移方程式为

dp[i][j]=max(dp[i][j],dp[i-a[k]][j-1]+b[i])

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 11000;
int a[N], b[N], dp[N][N];
int main() {
	int i, j, n, W, k, l;
	cin >> W >> n >> k;
	for (i = 1; i <= n; i++) {
		cin >> a[i] >> b[i];
	}
	for (i = 1; i <= n; i++) {
		for (j = W; j >= a[i]; j--) {
			for (l = k; l >= 1; l--) {
				dp[j][l] = max(dp[j][l], dp[j - a[i]][l - 1] + b[i]);
			}
		}
	}
	cout << dp[W][k] << endl;
	return 0;
}

posted @ 2024-07-05 17:35  ZhangDT  阅读(0)  评论(0编辑  收藏  举报