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列的数字,求最 ...
随机推荐
- docker使用命令汇总
docker命令 docker ps 容器列表 docker ps -a 所有容器列表,包含未运行的容器 docker image ls 镜像列表 docker logs -f xxx 容器日志 do ...
- R语言绘图:在地图上绘制热力图
使用ggplot2在地图上绘制热力图 ######*****绘制热力图代码*****####### interval <- seq(0, 150000, 25000)[-2] #设置价格区间 n ...
- 登録更新(BAPI)
購買管理(MM) * [BAPI_REQUISITION_CREATE] 購買依頼登録 * [BAPI_REQUISITION_CHANGE] 購買依頼変更 * [BAPI_REQUISITION_D ...
- Git的使用规范(一)
1.建议使用 git add.2.不建议使用git commit -a3.撤销没有add的git checkout . 这个命令我们可以好好的介绍一下,如果当你对文件进行了修改,你没有进行git ad ...
- linux挂载命令mount及U盘、移动硬盘的挂载
一.mount的命令格式是(注意mount只能在root权限下运行) mount dervice dir dervice是要挂载的设备,dir是挂载点 二.查看当前磁盘列表的设备 fdisk -l 显 ...
- 学习SQLite基本语句
SQLite 是一个开源的嵌入式关系数据库,实现自包容.零配置.支持事务的SQL数据库引擎. 其特点是高度便携.使用方便.结构紧凑.高效.可靠. 与其他数据库管理系统不同,SQLite 的安装和运行非 ...
- 白话HMM系列1——从一个缩略语还原的例子说起
HMM到底是一个什么样的东西,我想从我研究的一个应用场景开始说起.之所以想重新描述一下我对HMM的理解,是因为上次面试百度糯米的时候,自己没有把HMM在应用上说的很明白,不过糯米的那位郑姓面试官我也是 ...
- IOException: win32 io returned 267. Path:
unity3d在导出android项目时出现了这个错误,找了一圈也没找到原因,最后把项目名中空格去掉后OK了,坑啊!!!!
- js 操作表格行数的删减
沉溺了好几个月了,自从年假回来就一直在忙换工作的事情: 新环境.新同事,一如既往的工作, 那么闲话不多说,前两天师妹问我要一个类似于添加和删除的demo:闲暇时间我就参照一些代码写了一下, (发现有错 ...
- Android2.2以上的版本HttpURLConnection.getContentLength()获取的size跟下载下来的file的legth不相等
2.2以上的版本下载网络资源不完整无法更新.HttpURLConnection.getContentLength()获取的size跟下载下来的file的legth不等. 原因是:HttpURLConn ...