Problem Description
一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
Input
输入有多组数据,对于输入每组数据的第一行:二个整数,V(背包容量,V<=200),N(物品数量,N<=30);
第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。
第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。
Output
对于每组输入输出仅一行,一个数,表示最大总价值。
Sample Input
10 3 2 1 0 3 3 1 4 5 4
Sample Output
11
// 综合01背包,多重背包和完全背包,判断每种物品的数量,在进行单独处理
//标程:
#include<stdio.h> #include<string.h>
int dp[210]; struct ss { int w,val,n; }p[35]; int main() { //freopen("a.txt","r",stdin); int v,n,i,j,k,x; while(scanf("%d%d",&v,&n)!=EOF) { memset(dp,0,sizeof(dp)); for(i=0;i<n;i++) scanf("%d%d%d",&p[i].w,&p[i].val,&p[i].n); for(i=0;i<n;i++) { if(p[i].n==0) { for(j=0;j<p[i].w;j++) { for(k=j+p[i].w;k<=v;k+=p[i].w) if(dp[k]<dp[k-p[i].w]+p[i].val) dp[k]=dp[k-p[i].w]+p[i].val; } } else if(p[i].n==1) { for(j=v;j>=p[i].w;j--) if(dp[j-p[i].w]+p[i].val>dp[j]) dp[j]=dp[j-p[i].w]+p[i].val; } else { for(j=1;j<=p[i].n;j++) for(k=v;k>=j*p[i].w;k--) if(dp[k]<dp[k-p[i].w]+p[i].val) dp[k]=dp[k-p[i].w]+p[i].val; } } //for(x=1;x<=v;x++) printf("%d ",dp[x]); printf("\n"); printf("%d\n",dp[v]); } return 0; }