带有附件的背包问题,它属于01背包的变式
思路
解法一:转化为四种情况的分组背包求解
// luogu-judger-enable-o2
#include<iostream>
using namespace std;
int cnt[100],num1v[100],num1c[100],num2v[100][3],num2c[100][3],dp[100010];
int main(){
int n,m;
cin>>n>>m;
int v,q,p;
for(int i=1;i<=m;i++){
cin>>v>>q>>p;
if(p){
cnt[p]++;
num2v[p][cnt[p]]=v;
num2c[p][cnt[p]]=v*q;
}
else{
num1v[i]=v;
num1c[i]=v*q;
}
}
for(int i=1;i<=m;i++){
if(num1c[i])for(int j=n;j>=num1v[i];j--){
dp[j]=max(dp[j],dp[j-num1v[i]]+num1c[i]);
if(j>=num1v[i]+num2v[i][1]){
dp[j]=max(dp[j],dp[j-(num1v[i]+num2v[i][1])]+num1c[i]+num2c[i][1]);
}
if(j>=num1v[i]+num2v[i][2]){
dp[j]=max(dp[j],dp[j-(num1v[i]+num2v[i][2])]+num1c[i]+num2c[i][2]);
}
if(j>=num1v[i]+num2v[i][2]+num2v[i][1]){
dp[j]=max(dp[j],dp[j-(num1v[i]+num2v[i][1]+num2v[i][2])]+num1c[i]+num2c[i][1]+num2c[i][2]);
}
}
}
cout<<dp[n]<<endl;
}
解法二:非树形有依赖的背包问题(只有两类物品:主件,附件)

本文深入探讨了带有附件的背包问题,这是一种01背包问题的变式,主要讲解了两种解题策略:一种是通过分组背包转换为四种情况求解;另一种是非树形有依赖的背包问题解决方法,专注于主件和附件的处理。
1070





