1435: 混合背包
时间限制: 1 Sec 内存限制: 128 MB提交: 8 解决: 8
[ 提交][ 状态][ 讨论版]
题目描述
一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
输入
第一行:二个整数,V(背包容量,V<=200),N(物品数量,N<=30);
第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。输出
仅一行,一个数,表示最大总价值。
样例输入
10 32 1 03 3 14 5 4
样例输出
11
提示
来源
混合背包,就是把01背包,多重背包以及完全背包结合起来,然后分而治之,按照各自的规则运算
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Node{
int Wi,Ci,Pi;
}a[35];
int dp[210];
int main(){
int V,N;
while(scanf("%d %d",&V,&N)!=EOF){
memset(dp,0,sizeof(dp));
for(int i=0;i<N;i++){
scanf("%d %d %d",&a[i].Wi,&a[i].Ci,&a[i].Pi);
}
for(int i=0;i<N;i++){
if(a[i].Pi==0){
//完全背包
for(int j=a[i].Wi;j<=V;j++){
dp[j]=max(dp[j],dp[j-a[i].Wi]+a[i].Ci);
}
}
else if(a[i].Pi==1){
//01背包
for(int j=V;j>=a[i].Wi;j--){
dp[j]=max(dp[j],dp[j-a[i].Wi]+a[i].Ci);
}
}
else{
for(int k=0;k<a[i].Pi;k++){
for(int j=V;j>=a[i].Wi;j--){
dp[j]=max(dp[j],dp[j-a[i].Wi]+a[i].Ci);
}
}
}
}
printf("%d\n",dp[V]);
}
return 0;
}