Consumer
Time Limit: 4000/2000 MS (Java/Others)Memory Limit: 32768/65536 K (Java/Others)Total Submission(s): 611Accepted Submission(s): 313
Problem Description
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.
Input
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)
Output
For each test case,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 40 35 60
Sample Output
210
Source
2010 ACM-ICPC Multi-University Training Contest(2)——Host by BUPT
有很多个箱子,想买箱子中的物品必须先买下箱子
题目大意:
提供给你几个篮子,每个篮子有价格,还有其可以容纳的物品的个数,然后可容纳的物品有各自需要的价格(注意篮子有多个,每个篮子里面的物品可以不同,种数也可以不同),然后物品都有自己的权值(可以理解为重量之类的属性)。要买篮子里面的物品,你必须要先买这些物品所属的篮子。然后你一开始有一定的钱,要求你买到物品的权值最大(可以理解为重量最多)。
思路:
我一开始 想要暴力出来 这些物品的所有组合 然后分别加上Box 的价格 把它 变为简单的01背包 但是由于过于复杂而放弃 因为假如有10个数 暴力所有的组合 和麻烦
由于我个人的代码能力不足 不会啪 希望有人能拍出来 给我留个言 一定很感激 另外 那道经典的依赖背包题目 金明的预算方案 就可以这样去做 因为它只有2个依赖物品
参考了别人的思路:
用一个二维数组dp[0][]来表示当前买到的最优解。dp[1][]来表示把当前这个篮子买下后,得到的最优解
#include<stdio.h> #include<string.h> struct haha { int val; int cost; }a[55][15]; int dp[55][100010]; int mmax(int a,int b) { if(a>b) return a; else return b; } int main() { int n,m,i,j,k,Box[55],num[55]; while(scanf("%d %d",&n,&m)!=EOF) { memset(dp,sizeof(dp)); for(i=1;i<=n;i++) { scanf("%d %d",&Box[i],&num[i]); for(j=1;j<=num[i];j++) { scanf("%d %d",&a[i][j].cost,&a[i][j].val); } } for(i=1;i<=n;i++) { for(j=0;j<=m;j++) dp[1][j]=-999999999;//初始化为负数 能保证一定去实现1 即买Box for(k=1;k<=num[i];k++) for(j=m;j>=0;j--) { if(a[i][k].cost<=j) dp[1][j]=mmax(dp[1][j],dp[1][j-a[i][k].cost]+a[i][k].val); if(j>=a[i][k].cost+Box[i]) dp[1][j]=mmax(dp[1][j],dp[0][j-a[i][k].cost-Box[i]]+a[i][k].val);//从没有买Box的时候买Box后 和以前买了Box的比较取大的 } for(j=0;j<=m;j++) dp[0][j]=mmax(dp[0][j],dp[1][j]);//全部移动到下一层 下一层都是没买Box的 所以复制到dp[0][j] //dp[0][j]是指当前没有购买该组的任何一样东西 就不用买Box了 } printf("%d\n",mmax(dp[0][m],dp[1][m])); } return 0; }