多重背包(MultPack = ZeroOnePack + CompletePack)
HiHoCoder_offer6_04
题目4 : 奖券兑换
描述
小Hi在游乐园中获得了M张奖券,这些奖券可以用来兑换奖品。
可供兑换的奖品一共有N件。第i件奖品需要Wi张奖券才能兑换到,其价值是Pi。
小Hi使用不超过M张奖券所能兑换到的最大奖品总价值是多少?
输入
第一行两个整数N,M。
接下来N行,每行两个整数Wi,Pi。
对于 50%的数据: 1≤N,M≤1000
对于 100%的数据: 1≤N,M≤105,1≤Pi,Wi≤10。
输出
一行一个整数,表示最大的价值。
- 样例输入
-
3 10
2 3
8 8
10 10 - 样例输出
-
11
明显是一个01背包问题,背了一下结果:过了一半的数据,剩下的TLE了。 仔细观察数据, 1 <= n , m <= 100000, 1 <= wi , pi <= 10。明显每个物品的价值和容量都非常小,也就是说不同容量不同不价值的物品最多有:10 * 10 = 100种。
既然这个数据项这么小,那么它就是这个问题的突破口。对于每一个物品,已知它的num(数量 )和 weight(重量) & value(价值),刚好可以使用多重背包。加上二进制优化,复杂度O(10 * 10 * log 100000);
代码:
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int num[][];
int dp[]; void CompletePack(int weight, int value, int totWeight)
{
for(int w = weight; w <= totWeight; w ++){
dp[w] = max(dp[w], dp[w - weight] + value);
}
} void zeroOnePack(int weight, int value, int totWeight)
{
for(int w = totWeight; w >= weight; w --){
dp[w] = max(dp[w], dp[w - weight] + value);
}
} void multiPack(int weight, int value, int totWeight)
{
if(weight * num[weight][value] > totWeight){
CompletePack(weight, value, totWeight);
}else{
int k = , tmpNum = num[weight][value];
while(k < tmpNum){
zeroOnePack(k * weight, k * value, totWeight);
tmpNum -= k;
k <<= ;
}
zeroOnePack(tmpNum * weight, tmpNum * value, totWeight);
}
} int main()
{
int n,m,weight,value;
cin>>n>>m;
for(int i = ; i < n; i ++){
scanf("%d%d",&weight, &value);
num[weight][value] ++;
}
for(int i = ; i <= ; i ++){
for(int j = ; j <= ; j ++){
multiPack(i, j, m);
}
}
printf("%d\n",dp[m]);
return ;
}
————————++++++————————
多重背包(MultPack = ZeroOnePack + CompletePack)的更多相关文章
- HDU-2844 Coins(多重背包)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- hdu 2191 多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
http://acm.hdu.edu.cn/showproblem.php?pid=2191 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的 ...
- DP大作战——多重背包
题目描述 在之前的上机中,零崎已经出过了01背包和完全背包,也介绍了使用-1初始化容量限定背包必须装满这种小技巧,接下来的背包问题相对有些难度,可以说是01背包和完全背包的进阶问题. 多重背包:物品可 ...
- poj 2392 多重背包
题意:有几个砖,给出高度,能放的最大高度和数目,求这些砖能垒成的最大高度 依据lim排个序,按一层一层进行背包 #include<cstdio> #include<iostream& ...
- poj 1276 多重背包
735 3 4 125 6 5 3 350 //735的最大额,3种,4个125,6个5,3个350 633 4 500 30 6 100 1 5 0 1 735 0 0 3 10 100 10 50 ...
- hdu 1059 多重背包
题意:价值分别为1,2,3,4,5,6的物品个数分别为a[1],a[2],a[3],a[4],a[5],a[6],问能不能分成两堆价值相等的. 解法:转化成多重背包 #include<stdio ...
- poj1276 多重背包
//Accepted 1100 KB 47 ms //多重背包 #include <cstdio> #include <cstring> #include <iostre ...
- poj2392 多重背包
//Accepted 868 KB 188 ms //多重背包 #include <cstdio> #include <cstring> #include <iostre ...
- poj1014 dp 多重背包
//Accepted 624 KB 16 ms //dp 背包 多重背包 #include <cstdio> #include <cstring> #include <i ...
随机推荐
- 后台工具screen
之前在putty之类的远程命令行操作服务器的时候,遇到关闭软件,对应的操作就会关闭.很多时候,就是开着电脑,然后挂在那里,虽然不用电脑跑,但是也耗电...主要是putty这些软件有时候会伴随黑屏崩掉. ...
- 3.1.1 简单的 grep
grep 最简单的用法就是使用固定字符串: [many@avention Desktop]$ who many :0 2019- ...
- DS26C31M和DS26C32AM
DS26C31M是产生差分信号的芯片,实际使用的时候,测得在5V供电的情况下,输出+和输出-的压差是5V其中输出+和输入的特性相同. DS26C32AM是接收差分信号的芯片,与DS26C31M可以向配 ...
- 线程 synchronized锁机制
脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...
- 【Codeforces 159B】Matchmaker
[链接] 我是链接,点我呀:) [题意] 笔和笔盖 笔有颜色和直径 笔盖也有颜色和直径 笔盖和笔如果直径相等 那么称为good 如果笔盖和笔直径相等.颜色也相等,那么称为very good 问你怎样安 ...
- 不动点(Fixed Point)
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51735818 在数学中,函数的不动点( ...
- 线段树题集 (cf版)
lazy区间修改 : http://acm.hdu.edu.cn/showproblem.php?pid=4902 (hdu4902) http://acm.hdu.edu.cn/showpr ...
- 深刻理解Python中的元类(metaclass)--代码实践
根据http://blog.jobbole.com/21351/所作的代码实践. 这篇讲得不错,但以我现在的水平,用到的机会是很少的啦... #coding=utf-8 class ObjectCre ...
- [poj2425]A Chess Game_博弈论
A Chess Game poj-2425 题目大意:题目链接 注释:略. 想法:这个题就是为什么必须要用记忆化搜索.因为压根就不知道后继是谁. 我们通过SG定理可知:当前游戏的SG值等于所有子游戏的 ...
- iptables中增加/删除/查询/修改的基本操作
虽然在Ubuntu使用了UFW来简化iptables的操作,但是UFW只针对防火墙方面,转发方面没有涉及,所以要弄懂其中的原理,还是必须回归到iptables中.CentOS也是如此.下面是针对ipt ...