混合背包

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)。

Output

对于每组输入输出仅一行,一个数,表示最大总价值。

Sample Input

10 3
2 1 0
3 3 1
4 5 4

Sample Output

11
 
   
#include
#include
using namespace std;
int main()
{
	//freopen("a.txt","r",stdin);
	int v,n;
	while(scanf("%d%d",&v,&n)!=EOF)
	{
		int w[1000],c[1000],p[1000],i,k=0,t,j,f[202]={0};
		for(i=1;i<=n;i++)
		{
			t=1;
			scanf("%d%d%d",&w[i],&c[i],&p[i]);
			if(p[i]>1)   //将有限个相同价格的物品转化为不同价格的单个物品 
			{
				while(p[i]>t)
				{
					k++;
					w[n+k]=w[i]*t;
					c[n+k]=c[i]*t;
					p[n+k]=1;
					p[i]-=t;
					t*=2;
				}
				w[i]*=p[i];
				c[i]*=p[i];
				p[i]=1;
			}
		}
		for(i=1;i<=n+k;i++)
		 if(p[i]==1)   //判断是01背包还是完全背包 
		  for(j=v;j>=w[i];j--)
		   f[j]=f[j]>f[j-w[i]]+c[i] ? f[j]:f[j-w[i]]+c[i];
		 else
		  for(j=w[i];j<=v;j++)
		   f[j]=f[j]>f[j-w[i]]+c[i] ? f[j]:f[j-w[i]]+c[i];
		printf("%d\n",f[v]);
	}
	return 0;
}


你可能感兴趣的:(背包问题)