题目链接:HRBUST 1377 金明的预算方案
题目大意:
题解:
将主件和其附件分为一组,组内包含主件、主件和附件\(1\)、主件和附件\(2\)、主件和附件\(1,2\)至多四个物品。
对所有组进行\(01\)背包,每组只能选一个。
#include <cstring>
#include <iostream>
using namespace std;
int n, m, w[65][4], v[65][4], dp[32010];
int main() {
while (cin >> n >> m) {
memset(dp, 0, sizeof(dp));
memset(w, 0, sizeof(w));
memset(v, 0, sizeof(v));
for (int i = 1, a, b, c; i <= m; ++i) {
cin >> a >> b >> c;
if (!c) { // 是主件
w[i][0] = a * b;
v[i][0] = a;
} else { // 是附件
if (!w[c][1]) {
w[c][1] = a * b;
v[c][1] = a;
} else {
w[c][2] = a * b;
v[c][2] = a;
}
}
}
for (int i = 1; i <= m; ++i) {
for (int j = n; j >= v[i][0]; --j) {
dp[j] = max(dp[j], dp[j - v[i][0]] + w[i][0]); // 只买主件
// 如果没有相应附件则附件值为0,不影响
if (v[i][0] + v[i][1] + v[i][2] <= j) { // 买主件和两个附件
dp[j] = max(dp[j], dp[j - v[i][1] - v[i][2] - v[i][0]] + w[i][1] + w[i][2] + w[i][0]);
}
if (v[i][0] + v[i][1] <= j) { // 买主件和一种附件
dp[j] = max(dp[j], dp[j - v[i][1] - v[i][0]] + w[i][1] + w[i][0]);
}
if (v[i][0] + v[i][2] <= j) { // 买主件和另一种附件
dp[j] = max(dp[j], dp[j - v[i][2] - v[i][0]] + w[i][2] + w[i][0]);
}
}
}
cout << dp[n] << endl;
}
return 0;
}