Files
exercises/dp/backpack_dp/NOIP2006S_jinming_budget_dp_knapsack.cpp
T
2026-09-05 11:05:50 +08:00

87 lines
2.0 KiB
C++

#include <iostream>
#include <vector>
using namespace std;
struct FlatItem {
int weight, value;
FlatItem operator+(const FlatItem& other) const {
return {.weight = weight + other.weight, .value = value + other.value};
}
};
struct OriginalItem {
FlatItem item{};
vector<FlatItem> sons;
};
constexpr int MAX_N = 65, MAX_CAPACITY = 32005;
int capacity, n;
vector<OriginalItem> items;
vector<FlatItem> flat_items;
int fathers_temp[MAX_N];
int dp[MAX_CAPACITY];
vector<FlatItem> generate_flat_items(OriginalItem item) {
switch (item.sons.size()) {
case 0:
return vector{item.item};
case 1:
return vector{
item.item,
item.sons[0] + item.item,
};
case 2:
return vector{
item.item,
item.sons[0] + item.item,
item.sons[1] + item.item,
item.sons[0] + item.sons[1] + item.item,
};
default:
throw logic_error("Invalid item size!");
}
}
void solve_dp() {
for (int i = 0; i < n; i++) {
if (items[i].item.value == -1) { continue; }
for (int w=capacity; w>=1; w--) {
// dp[w] = dp[w] // 不买
for (const auto& [weight, value] : generate_flat_items(items[i])) {
if (w >= weight) {
dp[w] = max(dp[w], dp[w - weight] + value);
}
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> capacity >> n;
items.resize(n);
for (int i = 0; i < n; i++) {
cin >> items[i].item.weight >> items[i].item.value >> fathers_temp[i];
items[i].item.value *= items[i].item.weight; // 题意
}
for (int i = 0; i < n; i++) {
if (fathers_temp[i] != 0) {
items[fathers_temp[i] - 1].sons.push_back(items[i].item);
items[i].item.value = -1; // 删掉这个元素!
}
}
solve_dp();
cout << dp[capacity] << endl;
return 0;
}