2.0-1背包
算法思路:
此题在最基础的0-1背包问题上加了一个体积限制,其基本思想不变。
记录容量为1—c,容积为1—d的背包处理前i的物品的最大价值
考虑能不能装下第i个物品,装得的话考虑值不值得装
用一个回溯来记录选择了哪些物品
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define N 100
#define V 100
#define W 100
int n,c,d;
int w[N],b[N],v[N];
int dp[N][W][V]; //dp[i][j][k]表示用容量为j, 容积为k的背包来处理前i个物品
int select[N];
void findAns(int n1,int c1,int d1){
if(n1>0){
if(dp[n1][c1][d1] == dp[n1-1][c1][d1]){
select[n1] = 0;
findAns(n1-1,c1,d1);
}
else if(c1 >= w[n1] && d1 >= b[n1] && dp[n1][c1][d1] == dp[n1-1][c1-w[n1]][d1-b[n1]]+v[n1]){
select[n1] = 1;
findAns(n1-1,c1-w[n1],d1-b[n1]);
}
}
}
int main(){
int n;
scanf("%d%d%d",&n,&c,&d);
for(int i=1;i<=n;i++) scanf("%d%d%d",&w[i],&b[i],&v[i]);
for(int i=1;i<=n;i++){
for(int j=1;j<=c;j++){
for(int k=1;k<=d;k++){
if((j-w[i] >= 0) && (k-b[i] >= 0)){
dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-w[i]][k-b[i]]+v[i]);
}
else{
dp[i][j][k]=dp[i-1][j][k];
}
}
}
}
findAns(n,c,d);
printf("最大价值为:%d\n",dp[n][c][d]);
for(int m=1;m<=n;m++){
//if(select[m]) printf("%d ",m);
printf("%d ",select[m]);
}
return 0;
}