题目
题解
–这是一个美丽的01背包问题,只不过物品与物品之间加上了一点点的联系
–f[i] 表示剩下 i 元时所取到的最大价值
–本来对于每个物品,有取或不取两种方式
而现在,我们把没有附件的主件也用一个花费为0,价值也为0的附件处理
然后只对主件分析:
这样,对每个主件都有5种决策
1.只选主件
2.选主件和1号
3.选主件和2号
4.选主件和1号,2号
5.都不选
这样,dp的三要素都齐了,代码也出来啦
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=105;
int n,m;
int v[MAXN],p[MAXN];
bool isd[MAXN]; //是否为主件
int l[MAXN],r[MAXN]; //附件1,和附件2 的编号
long long f[32005];
int main(){
// freopen("budget.in","r",stdin);
// freopen("budget.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=m;i++){
int dad;
scanf("%d%d%d",&v[i],&p[i],&dad);
p[i]*=v[i];
if(dad){
if(!l[dad])
l[dad]=i;
else
r[dad]=i;
}
else
isd[i]=1;
}
for(int i=1;i<=m;i++){
if(isd[i]){
for(int j=n;j>=0;j--){
int x1=v[i],
x2=v[i]+v[l[i]],
x3=v[i]+v[r[i]],
x4=v[i]+v[l[i]]+v[r[i]];
int y1=p[i],
y2=p[i]+p[l[i]],
y3=p[i]+p[r[i]],
y4=p[i]+p[l[i]]+p[r[i]];
if(j>=x1)
f[j]=max(f[j],f[j-x1]+y1);
if(j>=x2)
f[j]=max(f[j],f[j-x2]+y2);
if(j>=x3)
f[j]=max(f[j],f[j-x3]+y3);
if(j>=x4)
f[j]=max(f[j],f[j-x4]+y4);
}
}
}
cout<<f[n];
return 0;
}