以主键为物品,附件作为主件的不同开销和价值选项,按照01背包的算法解决该问题。
#include <iostream>
#include <map>
using namespace std;
struct Good {
int price;
int importance;
struct Good* next;
Good() {
next = nullptr;
}
};
int main() {
int total_money;
int total_goods;
map<int, Good*> things;
int dp[61][3200] = {0};
scanf("%d %d", &total_money, &total_goods);
total_money /= 10;
// 读取物品,按照主件进行存放,主件为表头元素,后续元素为附件
for(int i=1; i<=total_goods; i++) {
Good* item = new Good;
int num;
scanf("%d %d %d", &(item->price), &(item->importance), &num);
item->price /= 10;
if (num == 0) {
item->next = things[i];
things[i] = item;
} else {
if (things.count(num) == 0) {
things[i] = item;
} else {
Good* tmp = things[num]->next;
things[num]->next = item;
item->next = tmp;
}
}
}
int thing_index = 1;
for(auto i=things.begin(); i != things.end(); i++) {
for(int m = 1; m <= total_money; m++) {
Good* item = i->second;
// 将主附件的开销和价值保存到数组中
int money[3];
int value[3];
for(int j=0; j<3; j++) {
if (item != nullptr) {
money[j] = item->price;
value[j] = item->price * item->importance;
item = item->next;
} else {
money[j] = 0;
value[j] = 0;
}
}
int value_total;
int cur_money;
int cur_value;
value_total = dp[thing_index - 1][m];
cur_money = money[0];
cur_value = value[0];
if (m >= cur_money) {
value_total = max(dp[thing_index - 1][m - cur_money] + cur_value, value_total);
}
cur_money = money[0] + money[1];
cur_value = value[0] + value[1];
if (m >= cur_money) {
value_total = max(dp[thing_index - 1][m - cur_money] + cur_value, value_total);
}
cur_money = money[0] + money[2];
cur_value = value[0] + value[2];
if (m >= cur_money) {
value_total = max(dp[thing_index - 1][m - cur_money] + cur_value, value_total);
}
cur_money = money[0] + money[1] + money[2];
cur_value = value[0] + value[1] + value[2];
if (m >= cur_money) {
value_total = max(dp[thing_index - 1][m - cur_money] + cur_value, value_total);
}
dp[thing_index][m] = value_total;
}
thing_index++;
}
cout << dp[things.size()][total_money] * 10;
return 0;
} 
京公网安备 11010502036488号