$ Coins $



$ solution: $

这道题很短,开门见山,很明显的告诉了读者这是一道多重背包。但是这道题的数据范围很不友好,它不允许我们直接将这一题当做01背包去做。于是我们得想一想优化。

** $ bitset $ 优化:** 这个是我最先想到的,因为这道题只牵扯到了能不能买,就是一个“是”和“否”的问题,也就是说这个背包并没有什么权值(只有“可以”和“不可以”)然后就是单纯的状态转移。而这不是我们的二进制最擅长的东西吗?(我们利用某一个硬币的面额进行更新时,直接用二进制的左右移和或运算即可)不过这一题的范围有一点大,所以我们选择 $ bitset $

二进制拆分优化: 这个还是得学的,不过他确实很奇妙,就像我们可以用2的一些乘方来表达出所有的数一样,我们可以将这个思想带到多重背包里来。但是我们的二进制能表达出所有的数,而我并不一定需要它表示出那么多的数啊(比如 $ 20,21\dots 27,28 $ 可以表示出256以内所有的数,但我只要23以内怎么办? )!而解决这个问题就是二进制拆分最难思考的地方了。

二进制拆分的重点,博主决定举个例子,能理解这个例子很多问题就能迎刃而解了:我现在有一个集合 $ {20,21\dots 27,28 } $ 我可以用它表示出256以内的任何数,而如果我只想要它表示出189以内的数,那我只需要将集合里最大的数改为 $ 189-2^7 $ 即可也就是 $ {20,21\dots 27,189-27 } $ 可以表示出189以内的任何数。这里的证明留给大家,因为博主自己学习的时候发现如果单纯看证明理解似乎不如手算去感性理解。然后说明一下这个方法其实有一个地方需要注意(也是迷惑人最多的地方):博主为什么选择了从 $ 2^0\dots 2^7 $ 为什么又选了189这个数字,其实是因为必须满足向 $ 2^p $ 这个集合中最大的数一定是要比189这样的常数 $ k $ 小的最大的2的乘方!



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<bitset> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int using namespace std; bitset<100005> f; int n,m,ans;
int a[105]; inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
return sign?-res:res;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
while((n=qr())&&(m=qr())){
f&=1; f[0]=1; ans=0;
for(rg i=1;i<=n;++i) a[i]=qr();
for(rg i=1;i<=n;++i){ rg x=qr();
for(rg j=1;j<=x;x-=j,j<<=1)
if(a[i]*j<=m)f|=f<<(a[i]*j);
if(x*a[i]<=m)f|=f<<(x*a[i]);
}for(rg i=1;i<=m;++i) if(f[i])++ans;
printf("%d\n",ans);
}
return 0;
}

poj 1742 Coins(二进制拆分+bitset优化多重背包)的更多相关文章

  1. 【题解】Coins(二进制拆分+bitset)

    [题解]Coins(二进制拆分+bitset) [vj] 俗话说得好,bitset大法吼啊 这道题要不是他多组数据卡死了我复杂度算出来等于九千多万的选手我还不会想这种好办法233 考虑转移的实质是怎样 ...

  2. poj 1742 Coins(二进制优化多重背包)

    传送门 解题思路 多重背包,二进制优化.就是把每个物品拆分成一堆连续的\(2\)的幂加起来的形式,然后把最后剩下的也当成一个元素.直接类似\(0/1\)背包的跑就行了,时间复杂度\(O(nmlogc) ...

  3. POJ - 1276 二进制优化多重背包为01背包

    题意:直接说数据,735是目标值,然后3是后面有三种钱币,四张125的,六张五块的和三张350的. 思路:能够轻易的看出这是一个多重背包问题,735是背包的容量,那些钱币是物品,而且有一定的数量,是多 ...

  4. hdu 2844 poj 1742 Coins

    hdu 2844 poj 1742 Coins 题目相同,但是时限不同,原本上面的多重背包我初始化为0,f[0] = 1;用位或进行优化,f[i]=1表示可以兑成i,0表示不能. 在poj上运行时间正 ...

  5. [Bzoj 1192][HNOI2006]鬼谷子的钱袋(二进制优化多重背包)

    (人生第一篇bzoj题解有点激动 首先介绍一下题目: 看它题目那么长,其实意思就是给定一个数a,求将其拆分成n个数,通过这n个数可以表示出1~a中所有数的方案中,求最小的n. 您看懂了嘛?不懂咱来举个 ...

  6. poj1014二进制优化多重背包

    Dividing Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 53029   Accepted: 13506 Descri ...

  7. BZOJ 1531 二进制优化多重背包

    思路: 讲道理我应该写单调队列优化多重背包的 但是我不会啊 但是我现在! 还不会啊 我就写了个二进制优化的.. 过了 //By SiriusRen #include <cstdio> #i ...

  8. 51nod 1086 背包问题 V2(二进制优化多重背包)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1086 题解:怎么用二进制优化多重背包,举一个例子就明白了. ...

  9. [tyvj-1194]划分大理石 二进制优化多重背包

    突然发现这个自己还不会... 其实也不难,就和快速幂感觉很像,把物品数量二进制拆分一下,01背包即可 我是咸鱼 #include <cstdio> #include <cstring ...

随机推荐

  1. Unix(AIX,Linux)

    AIX全名为(Advanced Interactive Executive),它是IBM公司的UNIX操作系统. 虽然Linux和aix都是Unix兼容的操作系统,但他们在不同的领域存在各自的特点和差 ...

  2. 【(好题)组合数+Lucas定理+公式递推(lowbit+滚动数组)+打表找规律】2017多校训练七 HDU 6129 Just do it

    http://acm.hdu.edu.cn/showproblem.php?pid=6129 [题意] 对于一个长度为n的序列a,我们可以计算b[i]=a1^a2^......^ai,这样得到序列b ...

  3. spring5响应式编程

    1.Spring5新特性    2.响应式编程响应式编程:非阻塞应用程序,借助异步和事件驱动还有少量的线程垂直伸缩,而非横向伸缩(分布式集群)当Http连接缓慢的时候,从数据库到Http数据响应中也会 ...

  4. Java 学习(3):java 对象和类

    目录: --- 对象 --- 类 --- 源文件的声明规则 --- Java 包 对象: 对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种: ...

  5. 【Codeforces Round #504 (Div. 1 + Div. 2) 】

    A:https://www.cnblogs.com/myx12345/p/9843678.html B:https://www.cnblogs.com/myx12345/p/9843709.html ...

  6. git status检测不到文件变化

    SourceTree(Git)无法检测新增文件的解决方法 有时候使用git管理软件SourceTree会遇到往项目里新增了文件,软件却没有任何反应的问题,这多发生在git合并出错而只能重新git的情况 ...

  7. 第2章 CentOS网络配置

    一.配置说明 1.1 说明 1.本文以VM仅本机模式下与宿主机的网络配置为例. 1.2 达成目标 1.Windows能ping通centOS 2 centOS能够ping通Windows 3 cent ...

  8. Ubuntu 16.04下在Shell终端下使用nautilus快速打开窗口文件夹

    Ubunut 16.04默认使用nautilus进行管理资源文件夹,nautilus默认是支持参数传递的. 使用: nautilus /dirurl 打开当前文件夹(可以使用$PWD代替): naut ...

  9. 用JS过滤Emoji表情的输入

    本文为原创,转载请注明出处: cnzt       文章:cnzt-p http://www.cnblogs.com/zt-blog/p/6773854.html 在前端页面开发过程中,总会碰到不允许 ...

  10. android 加一个按钮,退出程序

    package com.example.yanlei.yl; import android.graphics.Color; import android.support.v7.app.AppCompa ...