首页 > ACM题库 > HDU-杭电 > HDU 3449-Consumer-背包问题-[解题报告]HOJ
2014
03-23

HDU 3449-Consumer-背包问题-[解题报告]HOJ

Consumer

问题描述 :

FJ is going to do some shopping, and before that, he needs some boxes to carry the different kinds of stuff he is going to buy. Each box is assigned to carry some specific kinds of stuff (that is to say, if he is going to buy one of these stuff, he has to buy the box beforehand). Each kind of stuff has its own value. Now FJ only has an amount of W dollars for shopping, he intends to get the highest value with the money.

输入:

The first line will contain two integers, n (the number of boxes 1 <= n <= 50), w (the amount of money FJ has, 1 <= w <= 100000) Then n lines follow. Each line contains the following number pi (the price of the ith box 1<=pi<=1000), mi (1<=mi<=10 the number goods ith box can carry), and mi pairs of numbers, the price cj (1<=cj<=100), the value vj(1<=vj<=1000000)

输出:

The first line will contain two integers, n (the number of boxes 1 <= n <= 50), w (the amount of money FJ has, 1 <= w <= 100000) Then n lines follow. Each line contains the following number pi (the price of the ith box 1<=pi<=1000), mi (1<=mi<=10 the number goods ith box can carry), and mi pairs of numbers, the price cj (1<=cj<=100), the value vj(1<=vj<=1000000)

样例输入:

3 800
300 2 30 50 25 80
600 1 50 130
400 3 40 70 30 40 35 60

样例输出:

210

#include<stdio.h>
#include<string.h>
#define wsize 100010
#define nsize 65
#define msize 11
int dp[nsize][wsize];
int n,t,box,num;
int max(int a,int b)
{
	return a>b?a:b;
}
int main ()
{
	int i,j,k;
	while(scanf("%d %d",&n,&t)!=EOF)
	{
		memset(dp,-1,sizeof(dp));   //有依赖关系,要赋初值-1
		memset(dp[0],0,sizeof(dp[0]));
		for(i=1;i<=n;i++)
		{
			scanf("%d %d",&box,&num);
			for(k=box;k<=t;k++)
				dp[i][k]=dp[i-1][k-box];  //先让i层买盒子,因为盒子没有价值,所以直接等于上一层的花费+盒子钱
			for(j=0;j<num;j++)             //在已花费盒子钱的基础上,此时再对dp[i]层做01背包,即i层一个盒子多种物品的最大价值       
			{
				int c,w;
				scanf("%d %d",&c,&w); 
				for(k=t;k>=c;k--)    
				{
					if(dp[i][k-c]!=-1)  //注意依赖背包有不可能的情况,这里即k买不到盒子和这个物品,不能装物品
						dp[i][k]=max(dp[i][k],dp[i][k-c]+w);  // 这里不能dp[i][k]=max(dp[i][j],dp[i][k-box-c]+w) 因为已经										买过盒子了,这个表达式代表一个盒子基础上一个物品带一个盒子
				}
			}
			for(j=0;j<=t;j++)
			{               // 不买这组    买这组
				dp[i][j]=max(dp[i-1][j],dp[i][j]);  //不要忘了考虑不选当前组的情况(不是必选)
			}
		}
		printf("%d\n",dp[n][t]);
	}
	return 0;
}

参考:http://blog.csdn.net/yan_____/article/details/8539745


  1. 题目需要求解的是最小值,而且没有考虑可能存在环,比如
    0 0 0 0 0
    1 1 1 1 0
    1 0 0 0 0
    1 0 1 0 1
    1 0 0 0 0
    会陷入死循环