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中字典的遍历
用ipython运行情况如下: #新建字典 In [1]: name_cards = {'name':'sunwukong','QQ':'123124','addr':'秦皇岛'} #生成key对象 ...
- 006---hashlib模块
hashlib模块 HASH 一般翻译成散列,也可以叫哈希. 把任意长度的输入通过散列算法变换成固定的长度. 该转换是一种压缩映射 MD5 输入任意长度的信息,经过处理.输出为128位的信息(数字指纹 ...
- MongoDB入门---简介
最近呢,刚好有一些时间,所以就学习了一下新的数据库类型MongoDB.要想了解这个MongoDB,我们首先需要了解一个概念,那就是nosql(not only sql).一下就是官方的概念: NoSQ ...
- 一个适合变化的产品部署集成包(nginx+jdk+tomcat+nodejs+mysql+redis+mongo+MYSQL主主(读写分离)集群建立+代码包+持续上线+备份)
一.前言 最近公司做了一套新产品,需要发布到不确定的硬件环境中(不同使用单位规模,使用人数,服务器提供的资源不同)若每次进行人工部署耗时费力,周期过长. 二.分析 具体的部署流程如下: 由上图流程进行 ...
- python,函数式编程
函数式编程: 特点:允许传递的参数是函数,且允许返回一个函数. 由于Python允许使用变量,因此,Python不是纯函数式编程语言,同样的输入可能输出不同,有副作用.纯函数式编程语言没有变量,输入和 ...
- 1826: [JSOI2010]缓存交换
1826: [JSOI2010]缓存交换 https://www.lydsy.com/JudgeOnline/problem.php?id=1826 分析: 简单的贪心,然后调啊调...最近怎么了,码 ...
- linux shell中读写操作mysql数据库
本文介绍了如何在shell中读写mysql数据库.主要介绍了如何在shell 中连接mysql数据库,如何在shell中创建数据库,创建表,插入csv文件,读取mysql数据库,导出mysql数据库为 ...
- Linux 下安装Python报错:zlib not available
问题描述: 在Linux下安装Python时出现一个错误:zipimport.ZipImportError: can't decompress data; zlib not available 详细错 ...
- 使用JDK自带的keytool工具生成证书
一.keytool 简介 keytool 是java用于管理密钥和证书的工具,它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及 ...
- C++学习006-条件运算符
这里我也理解的不咋的,大致意思应该就是根据运算符号 的优先级不同来解决的 条件运算符是其中一部分,而条件运算符具有右结合性,当一个表达式中出现多个条件运算符时,应该将位于最右边的问号与理他最近的冒号配 ...