物品间有主次品的依附关系,这里就将依附关系的物品讨论成几种情况,能拿几种分别做成一个新的物品,这几个新物品相当于是互斥关系 最多选一个 最后就当分组背包处理
这里由于只有一层依附关系,若有多层就从最底层出发分类处理。
#include<bits/stdc++.h>
using namespace std;
int dp[40000];
vector <int> cc[40000];
int main ()
{
int n,m;
cin>>n>>m;
int v[1000],p[1000],q[1000],w[1000];
for(int i=1;i<=m;++i)
{
cin>>v[i]>>p[i]>>q[i];
if(q[i]!=0)
{
cc[q[i]].push_back(i);
}
else cc[i].push_back(i);
}
int cnt=m;
for(int i=1;i<=m;++i)
{
if(cc[i].size())
{
int w1=0;
int v1=0;
for(int j=0;j<cc[i].size();++j)
{
if(cc[i][j]==i)
{
w1+=p[i]*v[i];
v1+=v[i];
w[i]=v[i]*p[i];
continue;
}
else {
v1+=v[cc[i][j]];
w1+=v[cc[i][j]]*p[cc[i][j]];
w[cc[i][j]]=v[cc[i][j]]*p[cc[i][j]]+p[i]*v[i];
v[cc[i][j]]+=v[i];
}
}
if(cc[i].size()>2)
{
w[++cnt]=w1;
v[cnt]=v1;
cc[i].push_back(cnt);
}
}
}
for(int i=1;i<=m;++i)
{
for(int j=n;j>=0;--j)
{
for(int k=0;k<cc[i].size();++k)
{
if(j>=v[cc[i][k]])
dp[j]=max(dp[j],dp[j-v[cc[i][k]]]+w[cc[i][k]]);
}
}
}
cout<<dp[n];
return 0;
}