有依赖背包,关系是一个森林,用树形DP做会超时。注意到题目中有提到,每个主件的附属品数量不超过2个,且附物品不会再有附属品。
因此我们可以采用分组背包对本题的状态进行集合划分,每组物品四种组合情况,枚举时采用二进制思想。
这里还用到了typedef , vector,通过此题学习他们的用法
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define v first
#define w second
using namespace std;
typedef pair<int ,int >PII;
const int N=62,M=32010;
int n,m;
PII master[N];
vector<PII> servent[N];
int f[M];
int main(){
cin>>m>>n;
for(int i=1;i<=n;i++){
int v,p,q;
cin>>v>>p>>q;
p*=v;
if(!q) master[i]={v,p};
else servent[q].push_back({v,p});
}
for(int i=1;i<=n;i++){
for(int u=m;u>=0;u--){
for(int j=0;j<1<<servent[i].size();j++){
int v=master[i].v,w=master[i].w;
for(int k=0;k<servent[i].size();k++){
if(j>>k&1){
v+=servent[i][k].v;
w+=servent[i][k].w;
}
}
if(u>=v)
f[u]=max(f[u],f[u-v]+w);
}
}
}
cout<<f[m]<<endl;
}
还有股票买卖IV和V
感谢各路大神有价值的分享