题目链接: 点我跳转
题目大意: 和01背包相比,物品的附件(最多两个)必须在选取了该物品的前提下才可以选择
题目分析: 如果是01背包,我们针对每一个物品考虑的情况有
- 不买电脑
- 买电脑
而现在的选择变成了
- 不买电脑
- 买电脑
- 买电脑+打印机
- 买电脑+扫描仪
- 买电脑+打印机+扫描仪
那我们的思路就很清晰了,不是01背包,而是01234背包(我自己瞎起的)
int dp[32005],v[65][4],w[65][4];
int main(){
int n,m;
cin>>n>>m;
for(int a,b,q,i=1;i<=m;i++){
cin>>a>>b>>q;
if(q){ //如果是一个附件
if(!v[q][1]) //如果主件没有附件
v[q][1] = v[q][0] + a, //购买主件+附件1
w[q][1] = w[q][0] + a*b;
else{ //如果主件已经有了一个附件
v[q][2] = v[q][0] + a, //购买主件+附件2
w[q][2] = w[q][0] + a*b,
v[q][3] = v[q][1] + a, //购买主件+附件1+附件2
w[q][3] = w[q][1] + a*b;
}
}else v[i][0] = a,w[i][0] = a*b;
}
for(int i=1;i<=m;i++){
if(v[i][0]) //如果是一个主件
for(int j=n;j>0;j--){
for(int k=0;k<4;k++){//将原来的dp[j] = max(dp[j],dp[j-v[i]]+w[i]);替换为5中情况
if(j>=v[i][k])
dp[j] = max(dp[j],dp[j-v[i][k]]+w[i][k]);
}
}
}
cout<<dp[n];
return 0;
}