榨取kkksc03
P1855 榨取kkksc03 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
输入:
6 10 10
1 1
2 3
3 2
2 5
5 2
4 3
输出:
4
这题是一道01背包的变形,二维费用背包题 (其实就是增加了一个背包容量的限制)
二维费用的背包问题是指:对于每件物品,具有两种不同的费用,选择这件物品必须同时付出这两种费用。对于每种费用都有一个可付出的最大值(背包容量)。问怎样选择物品可以得到最大的价值。
在这道题中,根据题意可知道,两个背包容量是时间 t[i] ,金钱m[i],
因为求的是愿望的个数,所以每份的价值都为1
状态转移方程:f[i][j][k]=max(f[i-1][j][k],f[i-1][j-m[i]][k-t[i]]+1)
这个方程也能像一般01背包一样进行维度压缩:
压缩后状态转移方程: f[j][k] = max(f[j][k], f[j - m[i]][k - t[i]] + 1);
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 300, INF = 0x3f3f3f3f;
int n, M, T;
int t[N], m[N]; //时间,金钱
int f[N][N];
int main() {
cin >> n >> M >> T;
for (int i = 1; i <= n; i++) {
cin >> m[i] >> t[i];
}
for (int i = 1; i <= n; i++) {
for (int j = M; j >= m[i]; j--) { //金钱
for (int k = T; k >= t[i]; k--) { //时间
f[j][k] = max(f[j][k], f[j - m[i]][k - t[i]] + 1);
}
}
}
cout << f[M][T];
return 0;
}
二维费用背包模板题
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 300, INF = 0x3f3f3f3f;
int n, V, M;
int v[N], m[N], w[N];
int f[N][N];
int main() {
cin >> n >> V >> M;
for (int i = 1; i <= n; i++) {
cin >> v[i] >> m[i] >> w[i];
}
for (int i = 1; i <= n; i++) {
for (int j = V; j >= v[i]; j--) { //体积
for (int k = M; k >= m[i]; k--) { //重量
f[j][k] = max(f[j][k], f[j - v[i]][k - m[i]] + w[i]);
}
}
}
cout << f[V][M];
return 0;
}