又看错题了。。。。。题目中所说的意思是一个一个主件最多能够有2个附件,这是在给数据的时候规定好的不是我们去控制的。所以在某种主件下最多就只有4中情况。
那么将这四种情况枚举出来,那么就和分组背包是一模一样的问题了。
分组背包:将组作为对外层循环,这样对于每个组选取哪一个就只和之前的那一组有关了,所以可以将当前组的所有物品都遍历一遍,那么他们在某个价值下的最大值要么是取当前要么不取。
那么使用滚动数组就可以让这个取与不取在内部遍历的时候就取到最大值。
//分组的背包问题,但是与雨巨演示的不同在于不同组有不同的选取数量。 #include <bits/stdc++.h> using namespace std; const int maxn = 70; struct Node { int v, p; }; Node a[maxn]; vector<Node> node[maxn]; int dp[32000+10]; int main() { int n, m; int v, p, q; cin>>m>>n; for (int i=1;i<=n;i++) { cin>>v>>p>>q; p = p*v; if (q==0) { a[i].v = v; a[i].p = p; } else { node[q].push_back({v, p}); } } for (int i=1;i<=n;i++) { // if (!a[i].v) continue; for (int j=m;j>=0;j--) { for (int l=0;l<=3;l++) { int v = a[i].v;int p = a[i].p; for (int k=0;k<node[i].size();k++) { if ((l>>k)&1) { v += node[i][k].v; p += node[i][k].p; } } if (j>=v) dp[j] = max(dp[j], dp[j-***bsp; } } } cout<<dp[m]; return 0; }