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.
|
|
|
|
#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的列表中,有了一个附件
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
比如物品A是1个主件,2个附件,应该最后有4种组合: 主件;主件+附件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;
|
|
|
|
|
}
|