Consumer [分组背包]
Consumer
**Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others)
Total Submission(s): 2657 Accepted Submission(s): 1397
**
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
题解
这是一道有依赖的分组背包的裸题
下面是背包九讲里面的一段话
考虑到所有这些策略都是互斥的(也就是说,你只能选择一种策略),所以一个主件和它的附件集合实际上对应于 P06 中的一个物品组,每个选择了主件又选择了若干个附件的策略对应于这个物品组中的一个物品,其费用和价值都是这个策略中的物品的值的和。但仅仅是这一步转化并不能给出一个好的算法,因为物品组中的物品还是像原问题的策略一样多。
再考虑 P06 中的一句话:可以对每组中的物品应用 P02 中“一个简单有效的优化”。这提示我们,对于一个物品组中的物品,所有费用相同的物品只留一个价值最大的,不影响结果。所以,我们可以对主件 i 的“附件集合”先进行一次 01 背包,得到费用依次为 0..V-c[i] 所有这些值时相应的最大价值 f’[0..V-c[i]] 。那么这个主件及它的附件集合相当于 V-c[i]+1 个物品的物品组,其中费用为 c[i]+k 的物品的价值为 f’[k]+w[i] 。也就是说原来指数级的策略中有很多策略都是冗余的,通过一次 01 背包后,将主件 i 转化为 V-c[i]+1 个物品的物品组,就可以直接应用 P06 的算法解决问题了。
设置一个dp数组,dp[i][j]表示到第i个箱子,用了j的钱获得的最大价值
根据这一段话,因为箱子里的物品不会再是箱子也就是箱子不会嵌套,我们可以把一个箱子及里面的物品看成一个物品组.
如果选这个箱子那么我们还可以选择选不选或者选几个里面的物品,而显然,花费价格相同的情况下,我们只需要保留一个最大价值,这并不会影响结果的正确性(一个小贪心),那么我们就可以在选了这个箱子的情况下(一定是只针对这个箱子),对里面的物品做一次01背包
在求出最大值之后我们还要和之前的箱子去比,相同情况下我们选择价值更大的箱子
因为每做一次,我们就比对一次,所以前一个一定是最大的,最后答案就保存在dp[n][v]里
for(int j=0;j<=V;j++) dp[i][j]=max(dp[i][j],dp[i-1][j]);
在处理单个箱子时,我们判断一下它的价格,即小于箱子价格的 都不能买,全部赋值成一个很小的数,注意是一个很小的数,不是-1或是0这样的,因为要保证它对后面的转移没有影响,即加上在多也依然是一个很小的数,取max一定取不到它
而大于等于它的就赋值成原来的价值,因为买箱子是没有价值的
for(int j=0;j<p;j++) dp[i][j]=-inf;
for(int j=p;j<=V;j++) dp[i][j]=dp[i-1][j-p];
具体AC代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#define MIN(a,b) (a)>(b)?(b):(a)
#define MAX(a,b) (a)>(b)?(a):(b)
#define in(i) (i=read())
using namespace std;
int read(){
int ans=0,f=1;
char i=getchar();
while(i<'0'||i>'9'){
if(i=='-') f=-1;
i=getchar();
}
while(i>='0' && i<='9'){
ans=(ans<<1)+(ans<<3)+i-'0';
i=getchar();
}
return ans*f;
}
const int inf=2000000;
int n,V;
int w[11],v[11];
int dp[51][100010];
int main()
{
while(cin>>n>>V){
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){
int p,m;
in(p);in(m);
for(int j=1;j<=m;j++){
in(w[j]);in(v[j]);
}
for(int j=0;j<p;j++) dp[i][j]=-inf;
for(int j=p;j<=V;j++) dp[i][j]=dp[i-1][j-p];
for(int j=1;j<=m;j++)
for(int k=V;k>=w[j];k--)
dp[i][k]=max(dp[i][k],dp[i][k-w[j]]+v[j]);
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;
}
Consumer [分组背包]的更多相关文章
- HDU 1712 ACboy needs your help(分组背包)
题意:给你n的课程组,每个课程组有m个课程,每个课程有一个完成时间与价值.问在m天内每组课程组最多选择一个,这样可以得到的最大价值是多少 题解:分组背包,其实就是每个课程组进行01背包,再在课程组内部 ...
- Codeforces Round #383 (Div. 2) D 分组背包
给出一群女孩的重量和颜值 和她们的朋友关系 现在有一个舞台 ab是朋友 bc是朋友 ac就是朋友 给出最大承重 可以邀请这些女孩来玩 对于每一个朋友团体 全邀请or邀请一个or不邀请 问能邀请的女孩的 ...
- HDU 3033 分组背包变形(每种至少一个)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 1712 分组背包
ACboy needs your help Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- Codeforces Round #383 (Div. 2) D. Arpa's weak amphitheater and Mehrdad's valuable Hoses(分组背包+dsu)
D. Arpa's weak amphitheater and Mehrdad's valuable Hoses Problem Description: Mehrdad wants to invit ...
- HDU3535AreYouBusy[混合背包 分组背包]
AreYouBusy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- POJ1837 Balance[分组背包]
Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 13717 Accepted: 8616 Descript ...
- Codevs1378选课[树形DP|两种做法(多叉转二叉|树形DP+分组背包)---(▼皿▼#)----^___^]
题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...
- hdu1712 分组背包
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1712 题意:有n门课程,和m天时间,完成mp[i][j]得到的价值为第i行j列的数字,求最 ...
随机推荐
- Python的scrapy之爬取boss直聘网站
在我们的项目中,单单分析一个51job网站的工作职位可能爬取结果不太理想,所以我又爬取了boss直聘网的工作,不过boss直聘的网站一次只能展示300个职位,所以我们一次也只能爬取300个职位. jo ...
- Scrapy之Cookie和代理
cookie cookie: 获取百度翻译某个词条的结果 一定要对start_requests方法进行重写. 两种解决方案: 1. Request()方法中给method属性赋值成post2. For ...
- C中 snprintf()函数的作用
函数原型:int snprintf(char* dest_str,size_t size,const char* format,...); 函数功能:先将可变参数 “…” 按照format的格式格式化 ...
- dotnet core 数据库
dotnet core 数据库 程序开发过程中,需要使用数据对数据进行存储,分析等.通常而言都会使用ORM来实现关系数据库与实体对象的转化,过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持 ...
- R语言绘图:时间序列分析 ggplot2绘制ACF PACF
R语言真是博大精深 方法一 Acf(gold[,2], type = "correlation",lag.max = 100) Acf(gold[,2], type = " ...
- Vue 去脚手架插件,自动加载vue文件
接上回 一些本质 本质上,去脚手架也好,读取vue文件也好,无非是维护options,每个Vue对象的初始化配置对象不触及Vue内部而言,在外部想怎么改都是可以的,只要保证options的正确,一切都 ...
- C#中利用iTextSharp开发二维码防伪标签(1)
开发的基本说明与尝试 一个亲戚朋友是做防伪码印刷的,之前的电话防伪.短信防伪都用Delphi给他设计,使用也挺不错,后来又加了一个基于asp的网页版防伪查询.由于业务需求,今年年初朋友又提成希望能够完 ...
- P2966 [USACO09DEC]牛收费路径Cow Toll Paths
P2966 [USACO09DEC]牛收费路径Cow Toll Paths 题目描述 Like everyone else, FJ is always thinking up ways to incr ...
- define 和 const常量有什么区别?
define在预处理阶段进行替换,const常量在编译阶段使用 宏不做类型检查,仅仅进行替换,const常量有数据类型,会执行类型检查 define不能调试,const常量可以调试 define定义的 ...
- jmeter使用BeanShell断言
1. 首先存储一个接口的响应结果,如在http请求的BeanShell PostProcessor: import java.io.UnsupportedEncodingException; Syst ...