Consumer
Time Limit: 4000/2000 MS(Java/Others) Memory Limit: 32768/65536 K (Java/Others)
Total Submission(s): 1671 Accepted Submission(s): 873
Problem Description
FJ is going to dosome shopping, and before that, he needs some boxes to carry the differentkinds of stuff he is going to buy. Each box is assigned to carry some specifickinds of stuff (that is to say, if he is going to buy one of these stuff, hehas to buy the box beforehand). Each kind of stuff has its own value. Now FJonly has an amount of W dollars for shopping, he intends to get the highestvalue with the money.
Input
The first linewill contain two integers, n (the number of boxes 1 <= n <= 50), w (theamount of money FJ has, 1 <= w <= 100000) Then n lines follow. Each linecontains 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 ofnumbers, the price cj (1<=cj<=100), the value vj(1<=vj<=1000000)
Output
For each testcase, output the maximum value FJ can get
Sample Input
3 800
300 2 30 50 25 80
600 1 50 130
400 3 40 70 30 4035 60
Sample Output
210
题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=3449
题意:
给出N个盒子,每个盒子标价为pi,其中装mi件物品,每件物品有自己的价格和价值,但买下某个物品必须先买下该物品所在的盒子,问在只有W的钱的前提下最多能获取的物品总价值;
思路:
有依赖的背包问题,背包九讲里有,主要的方法就是先对每个盒子进行一次01背包;然后再对背包内的物品进行01背包;
代码里用了dp[50][100000+10]的数组,实际可以用滚动数组优化空间;
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int dp[51][100000+10]; //其实可以用滚动数组优化
int box[51]; // 存放盒子的价格
int num[51]; //存放盒子中的物品数
struct ITEM{
int pri,val;
}item[500+10];//每件物品
int main (){
int n,v,cnt = 0;
while(~scanf("%d %d", &n, &v)){
cnt = 0;
for(int i = 1 ; i<= n ; i++){
scanf("%d %d",box+i,num+i);
for(int j = 0 ; j < num[i] ; j ++){
scanf("%d %d",&item[cnt].pri, &item[cnt].val);
cnt++;
}
}
memset(dp,0,sizeof(dp));
cnt = 0;
for(int i = 1 ; i <= n ; i ++){
for(int j = box[i]; j <= v; j ++){
dp[i][j] = dp[i-1][j-box[i]]; //买下盒子
}
//对盒子内的物品进行01背包
for(int k = cnt; k < cnt+num[i]; k ++){
for(int j = v; j >= item[k].pri+box[i]; j --)
dp[i][j] = max(dp[i][j],dp[i][j-item[k].pri]+item[k].val);
}
cnt+=num[i];
for(int j = 0 ; j <= v ; j ++)
dp[i][j] = max(dp[i][j],dp[i-1][j]);//不买盒子
}
cout << dp[n][v] <<endl;
}
return 0;
}