题目链接

思路

乍一看这是一个01背包的裸题。但是数据范围\(10^5\)是无法承受的。

但是发现\(p_i\)和\(w_i\)只有10,也就是说最多只有100种物品。所以可以对他们进行分组。然后用二进制优化多重背包来做。

二进制优化多重背包

多重背包是指限定物品数量的一种背包问题。

多重背包可以转化为01背包来解。也就是枚举当前这种物品选多少个。但是这种做法的复杂度是\(O(NVS)\)S是背包内物品数量。

然后考虑优化上面的方法。因为每个数字都是可以用二进制来拼凑出来的。所以可以把每个物品的数量拆分成\(2^x\)这样就能拆分除\(log\)个物品。每个物品的价值都是\(2^x \times w[i]\)的形式。体积都是\(2^x \times p[i]\)的形式。

比如一种物品价值为3,体积为2,数量为13。那么这个物品可以拆分成以下物品:

\[w:3 \times 1 p:2 \times 1 \\
w:3 \times 2 p:2 \times 2 \\
w:3 \times 4 p:2 \times 4 \\
w:3 \times 6 p:2 \times 6 \]

注意最后一个6并不是\(2^x\)。

代码

/*
* @Author: wxyww
* @Date: 2019-01-20 09:01:19
* @Last Modified time: 2019-01-20 09:07:51
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<bitset>
using namespace std;
typedef long long ll;
const int N = 100000 + 100;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int f[N],w[110],p[110],num[110],a[15][15];
int W,n,tot;
int main() {
n = read(),W = read();
int mx = 0,my = 0;
for(int i = 1;i <= n;++i) {
int x = read(),y = read();
a[x][y]++;
mx = max(mx,x);my = max(my,y);
}
for(int i = 1;i <= mx;++i) {
for(int j = 1;j <= my;++j) {
if(a[i][j]) {
++tot;
w[tot] = j;p[tot] = i;num[tot] = a[i][j];
}
}
}
for(int i = 1;i <= tot;++i) {
int k;
for(k = 1;num[i] - k >= k - 1;k <<= 1) {
for(int j = W;j >= p[i] * k;--j) {
f[j] = max(f[j],f[j - p[i] * k] + w[i] * k);
}
}
k = num[i] - k + 1;
for(int j = W;j >= p[i] * k;--j) {
f[j] = max(f[j],f[j - p[i] * k] + w[i] * k);
}
}
cout<<f[W];
return 0;
}

hihocoder1364 奖券兑换的更多相关文章

  1. hiho一下 第195周 奖券兑换[C solution][Accepted]

    时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi在游乐园中获得了M张奖券,这些奖券可以用来兑换奖品. 可供兑换的奖品一共有N件.第i件奖品需要Wi张奖券才能兑换到, ...

  2. 多重背包(MultPack = ZeroOnePack + CompletePack)

    HiHoCoder_offer6_04 题目4 : 奖券兑换 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi在游乐园中获得了M张奖券,这些奖券可以用来兑换奖品. ...

  3. MySQL_积分兑换的优惠券在某时间段内使用情况_ 20161215

    积分兑换的优惠券在某时间段内使用情况 SELECT a.城市,a.用户ID,a.优惠券ID,a.优惠券名称,a.积分兑换优惠券的张数,b.使用优惠券数量,a.积分兑换优惠券的金额,b.使用优惠券金额 ...

  4. 钱币兑换问题_完全背包&&拆分&&母函数

    ps:原来用新浪,可是代码的排版不是很好,所以用博客园啦,先容许我把从八月份开始的代码搬过来,从这里重新出发,希望这里可以一直见证我的成长. Time Limit: 2000/1000 MS (Jav ...

  5. hdu 1284 钱币兑换问题 完全背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1284 递推公式:dp[i] = sum(dp[i], dp[i-C]) /* 钱币兑换问题 Time ...

  6. 钱币兑换问题(hd1284)

    钱币兑换问题 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法.   Input 每行只有一个正整数N,N小于32768.   Output 对应每个输 ...

  7. HDU1284钱币兑换问题( 母函数打表)

    题意:在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. 原题http://acm.hdu.edu.cn/showproblem.php?pid=128 ...

  8. hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  9. hdu1284经典钱币兑换问题

    钱币兑换问题. 题目 http://acm.hdu.edu.cn/showproblem.php?pid=1284 完全背包. 这种是求背包问题最多的组合方案 参考了一些资料   http://blo ...

随机推荐

  1. MyBatis映射文件2(不支持自增的数据库解决方案/参数处理[单参、多参、命名参数])

    针对Oracle不支持自增的解决方案 Oracle不支持自增,但是它使用序列来模拟自增,每次插入数据的主键是从序列中拿到的值,那么如何获取这个值呢? <insert id="addEm ...

  2. StringBuilder与String有哪些区别?

    System.String具备不可修改性,在程序中这样的特性容易产生性能上的问题.针对这个问题.NET提供的StringBuilder类可以解决类似的问题. String 和 StringBuilde ...

  3. 思维导图,UML图,程序流程图制作从入门到精通

    工具: https://www.processon.com/ 第一 用例图 第二 时序图 第三 流程图

  4. Operation not allowed on a unidirectional dataset错误?

    关于网友提出的“ Operation not allowed on a unidirectional dataset错误?”问题疑问,本网通过在网上对“ Operation not allowed o ...

  5. 使用javaWeb的二大(Listener、Filter)组件实现分IP统计访问次数

    分析: 统计工作需要在所有资源之前都执行,那么就可以放到Filter中. 我们这个过滤器不打算做拦截操作!因为我们只是用来做统计 用什么东西来装载统计的数据.Map<String,Integer ...

  6. 实用的几个JS新特性(es 2016)

    在Chrome 55下测试,可用. 1.箭头函数(arrow function) 以前写的匿名函数是这样的 function(){}, 现在可以简单写成这样()=>{} 如果直接return,没 ...

  7. JSON in SQL Server 2016

    JSON functions in SQL Server enable you to analyze and query JSON data, transform JSON to relational ...

  8. int,String转换

    int -> String 第一种方法:s=i+""; //会产生两个String对象 第二种方法:s=String.valueOf(i); //直接使用String类的静态 ...

  9. John the Ripper-弱口令检测

    简介 John the Ripper免费的开源软件,是一个快速的密码破解工具,用于在已知密文的情况下尝试破解出明文的破解密码软件,支持目前大多数的加密算法,如DES.MD4.MD5等.它支持多种不同类 ...

  10. python之旅六【第六篇】模块

    json和pickle 用于序列化的两个模块json,用于字符串 和 python数据类型间进行转换pickle,用于python特有的类型 和 python的数据类型间进行转换 json模块提供了四 ...