每日一题-P1855 榨取kkksc03
榨取kkksc03
输入:
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; }