hdu 3732(背包,很不错的背包题目)

点击打开链接


题意:

很简单,n件物品,背包大小为C,每件物品有一定的价值和体积,求背包能装的最大价值。。


很明显的01背包,但是如果用01的模板来做,绝对要超时的,因为n<=100000,C<=10000。

但是是不是就不能做了呢,我们可以发现每件物品的价值和体积都<=10,所以我们可以根据价值和体积来区分物品,而不用标号。

但是这样就解决问题了么,还没有,当我们跟据价值和体积来区分物体的时候,还是可能有100000物品的可能,这时候就要涉及一个新的东西了,

多重背包的二进制优化,比如一件物品有13件,我们可以把这种物品分成1件,2件,4件,6件,这四种物品,这四种物品的价值分别为件数*单件的价值,然后按照01背包计算就可以了。。


#include"stdio.h"
#include"string.h"
#define N 11
int A[N][N];
int dp[10005];
int max(int a,int b)
{
	return a>b?a:b;
}
int main()
{
	int n,C;
	int i,j,k;
	while(scanf("%d%d",&n,&C)!=-1)
	{
		memset(A,0,sizeof(A));
		char s[11];
		for(i=0;i<n;i++)
		{
			scanf("%s%d%d",s,&j,&k);
			getchar();
			A[j][k]++;
		}
		memset(dp,0,sizeof(dp));
		for(int v=0;v<=10;v++)
		{
			for(int c=0;c<=10;c++)
			{
				int t=A[v][c];
				int k=1;
				if(t==0)continue;
				while(k<t)
				{
					for(i=C;i>=k*c;i--)
						dp[i]=max(dp[i],dp[i-k*c]+k*v);
					t-=k;
					k*=2;
				}
				for(i=C;i>=t*c;i--)
					dp[i]=max(dp[i],dp[i-t*c]+t*v);
			}
		}
		printf("%d\n",dp[C]);
	}
	return 0;
}


你可能感兴趣的:(dp,HDU,很不错的背包,多重背包的二进制优化)