题目:
题解:
想要购买附件,必须购买主件。
由于某主见最多拥有两个附件,所以可以枚举情况,分组背包。
如主件 x 有附件 x1 , x2 ;
有 x, x+x1, x+x2, x+x1+x2 四种情况,这四种情况是互相排斥的,只能选择一种,符合分组背包要求;
预处理貌似有点复杂,求指导代码简洁化;
正解还可以用有依赖的背包问题做,但这里附件数量很少,不必要那么麻烦。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
struct node{
int val;int wei;
};
const int N=100;
int dp[42000]={0};
int W,n,maxx;
vector<node> grp[N];
vector<node> wp[N];
void init(){
scanf("%d%d",&W,&n);
for(int i=1;i<=n;i++){
int v,q,p;
scanf("%d%d%d",&v,&q,&p);
if(p==0) grp[i].push_back((node){v*q,v});
else grp[p].push_back((node){v*q,v});
}
for(int i=1;i<=n;i++){
if(grp[i].empty()) continue;
int w=0,v=0;
v=grp[i][0].val,w=grp[i][0].wei;
wp[i].push_back((node){v,w});
if(grp[i].size()==1) continue;
v+=grp[i][1].val;w+=grp[i][1].wei;
wp[i].push_back((node){v,w});
if(grp[i].size()==2) continue;
v+=grp[i][2].val;w+=grp[i][2].wei;
wp[i].push_back((node){v,w});
wp[i].push_back((node){grp[i][0].val+grp[i][2].val,grp[i][0].wei+grp[i][2].wei});
}
}
int main(){
init();
/* for(int i=1;i<=n;i++){
printf("\n%d\n",i);
for(int k=0;k<wp[i].size();k++)
printf("val= %d wei= %d",wp[i][k].val,wp[i][k].wei);
}*/
for(int i=1;i<=n;i++){
if(wp[i].empty()) continue;
for(int j=W;j>=0;j--){
for(int k=0;k<wp[i].size();k++){
if(j-wp[i][k].wei<0) continue;
dp[j]=max(dp[j],dp[j-wp[i][k].wei]+wp[i][k].val);
maxx=max(maxx,dp[j]);
}
}
}
printf("%d",maxx);
return 0;
}