You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.8 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
// 利用循环法进行分组
const int N = 60, M = 32010;
struct Node {
int w, v;
};
int n, m;
vector<Node> a[N]; // 主件
vector<Node> b[N]; // 附件
int f[M];
int main() {
cin >> m >> n; // 容量上限,物品个数
for (int i = 1; i <= n; i++) {
int w, p, q;
cin >> w >> p >> q; // 体积,重要度,依赖哪个物品
if (!q) // 如果是主件
a[i].push_back({w, w * p}); // 记录主件i的列表中有了only主件i这个东西
else
b[q].push_back({w, w * p}); // 记录主件q的列表中有了一个附件
}
/*
A124 +1+2; +1+2;
:
+1+2=(+1)+2;2
*/
for (int i = 1; i <= n; i++)
for (auto c : b[i]) { // 遍历每个附件
int w = c.w, v = c.v;
int sz = a[i].size();
for (int j = 0; j < sz; j++)
a[i].push_back({a[i][j].w + w, a[i][j].v + v}); // 把扩展出来的组放在尾巴上
}
// 分组背包模板
for (int i = 1; i <= n; i++)
for (int j = m; j >= 0; j--)
for (int k = 0; k < a[i].size(); k++) // 注意这里k是从0开始因为vector的特点决定
if (j >= a[i][k].w)
f[j] = max(f[j], f[j - a[i][k].w] + a[i][k].v);
// 输出
printf("%d\n", f[m]);
return 0;
}