题目链接:点击打开链接
题意:
中文题,不在详述;
理解:
三维01背包;
递推式含义:dp[j][k][l] 表示用 j 的钱和 k 的积分 和 l 的免费次数能买到最大的价值;
递推式:dp[j][k][l] = max(dp[j][k][l], dp[j - a[i]][k][l] + w[i], dp[j][k - b[i]][l] + w[i], dp[j][k][l - 1] + w[i]);
其中的值根据代码定义;
注意的是和01背包不同的是在简化以后需要足以有的值是可以为 0 的;
即:j == 0 || k == 0 || l == 0;
代码如下:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MIN_INF = 1e-7;
const int MAX_INF = (1e9) + 7;
#define X first
#define Y second
int dp[105][105][10];
int a[105], b[105], w[105];
int main() {
int n, v1, v2, f;
while (cin >> n >> v1 >> v2 >> f) {
for (int i = 1; i <= n; ++i) {
cin >> a[i] >> b[i] >> w[i];
}
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; ++i) {
for (int j = v1; j >= 0; --j) {
for (int k = v2; k >= 0; --k) {
for (int l = f; l >= 0; --l) { //其中j、k、l都可以为0,而在简化的 01 背包中是不用算到零的;
int tp = 0;
if (j >= a[i]) {
tp = max(dp[j - a[i]][k][l] + w[i], tp);
}
if (k >= b[i]) {
tp = max(dp[j][k - b[i]][l] + w[i], tp);
}
if (l >= 1) {
tp = max(dp[j][k][l - 1] + w[i], tp);
}
dp[j][k][l] = max(dp[j][k][l], tp);
}
}
}
}
cout << dp[v1][v2][f] << endl;
}
return 0;
}