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

【vj】

俗话说得好,bitset大法吼啊

这道题要不是他多组数据卡死了我复杂度算出来等于九千多万的选手我还不会想这种好办法233

考虑转移的实质是怎样的,就是对于一个\(dp\)数组表,平移\(val_i \times num_i'\)位然后异或起来,这样就直接bitset开就好了。

背包问题的转移就不说了,优化就是利用二进制来优化,方法就是,我们可以知道所有数都是二进制表示出来的,根据加法交换律以及背包转移的方法,我们从小往大枚举\(2^x\le num_i\),然后把bitset平移\(2^x\)位后异或起来就好了。

但是有个天大的问题就是怎么保证我们的方案合法,也就是说保证我们的方案中不存在硬币用得过多。

实际上直接在循环的时候控制一下就好了,出来的方案就会\(\le num_i\)并且每个组合都会考虑到。

//@winlere
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset> using namespace std; typedef long long ll;
const int maxm=1e5+5;
const int maxn=1e2+5;
int val[maxn],num[maxn];
bitset < maxm > dp; int n,m;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
} int main(){
dp[0]=1;int ans=0;
while(scanf("%d%d",&n,&m),n||m){
for(register int t=1;t<=n;++t) val[t]=qr();
for(register int t=1;t<=n;++t) num[t]=qr();
dp&=1;
for(register int t=1;t<=n;++t){
for(register int i=1;i<=num[t];i<<=1)
if(1ll*i*val[t]<=m) dp|=dp<<(i*val[t]),num[t]-=i;
else num[t]-=i;
if(1ll*num[t]*val[t]<=m) dp|=dp<<(num[t]*val[t]);
}
for(register int t=1;t<=m;++t)
if(dp[t]) ++ans;
printf("%d\n",ans);
ans=0;
}
return 0;
}

【题解】Coins(二进制拆分+bitset)的更多相关文章

  1. poj 1742 Coins(二进制拆分+bitset优化多重背包)

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

  2. hdu 2844 coins(多重背包 二进制拆分法)

    Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...

  3. BZOJ 2069: [POI2004]ZAW(Dijkstra + 二进制拆分)

    题意 给定一个有 \(N\) 个点 \(M\) 条边的无向图, 每条无向边 最多只能经过一次 . 对于边 \((u, v)\) , 从 \(u\) 到 \(v\) 的代价为 \(a\) , 从 \(v ...

  4. HDU 4135:Co-prime(容斥+二进制拆分)

    Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  5. 2018.09.08 bzoj1531: [POI2005]Bank notes(二进制拆分优化背包)

    传送门 显然不能直接写多重背包. 这题可以用二进制拆分/单调队列优化(感觉二进制好写). 所谓二进制优化,就是把1~c[i]拆分成20,21,...2t,c[i]−2t+1+1" role= ...

  6. HDU1059 二进制拆分优化多重背包

    /*问你能不能将给出的资源平分成两半,那么我们就以一半为背包,运行多重背包模版 但是注意了,由于个数过大,直接运行会超时,所以要用二进制拆分每种的个数*/ #include<stdio.h> ...

  7. 【最短路】【dijkstra】【二进制拆分】hdu6166 Senior Pan

    题意:给你一张带权有向图,问你某个点集中,两两结点之间的最短路的最小值是多少. 其实就是dijkstra,只不过往堆里塞边的时候,要注意塞进去它是从集合中的哪个起始点过来的,然后在更新某个点的答案的时 ...

  8. 【找规律】【二进制拆分】hdu6129 Just do it

    给你数列a,问你对它作m次求前缀异或和之后的新数列是什么. 考虑a1对最终生成的数列的每一位的贡献,仅仅考虑奇偶性, 当m为2的幂次的时候,恰好是这样的 2^0 1 1 1 1 1 ... 2^1 1 ...

  9. [bzoj4300]绝世好题_二进制拆分

    绝世好题 bzoj-4300 题目大意:题目链接. 注释:略. 想法: 二进制拆分然后用一个数组单独存一下当前答案即可. Code: #include <iostream> #includ ...

随机推荐

  1. Autolayout 02

    Working with Auto Layout Programmatically 如果你在运行阶段添加或者移除views你就需要通过代码来添加约束来保证你的interface能正确适应size或者o ...

  2. 关闭火狐定期向“http://detectportal.firefox.com/”发包

    问题:最近发现火狐总是向http://detectportal.firefox.com/发包 办法:firefox地址栏输入 about:config,然后搜索找到 network.captive-p ...

  3. Linux学习之十二-Linux文件属性

    Linux文件属性 在Linux中,对于每个文件都有相应属性,以Linux中root用户家目录下新建文件a.txt为例,在a.txt中输入几个字符 使用命令ls -ild a.txt查看文件的权限等 ...

  4. UNP学习笔记(第三章:套接字编程简介)

    本章开始讲解套接字API. 套接字地址结构 IPv4套接字地址结构 它以sockaddr_in命名,下面给出它的POSIX定义 struct in_addr { in_addr_t s_addr; } ...

  5. ICON小工具如何使用

    对于ICON这个小资源,我们可以手动绘制.选择bmp图形的大小,尤其是旁边的选择工具(矩形或者弧形),我们可以通过选择工具挪动我们手动绘制的图标,其实图标只有中间那部分有用,其他没有用.还有最右边色拾 ...

  6. JS图片预加载插件

    在开发H5项目中有时候会遇到要加载大量图片的情况,利用预加载技术可以提高用户浏览时的体验. 1)概念:懒加载也叫延迟加载:JS图片延迟加载,延迟加载图片或符合某些条件时才加载某些图片.预加载:提前加载 ...

  7. iphone手机分辨率--持久维护

    6.5英寸 —— 1242 x 2688 px —— Xs Max 6.1英寸 —— 828 x 1792 px —— XR 5.8英寸 —— 1125 x 2436 px —— X/Xs 5.5英寸 ...

  8. Javascript模式(一) 单例模式

    function A(){ // 存储实例对象 var instance; // 重写构造函数,只返回闭包内的局部变量instance A = function(){ return instance; ...

  9. WCF TCP通信方式 通过IIS承载调试

    http://www.cnblogs.com/nikymaco/archive/2012/10/08/2715954.html IIS Express服务器只支持http/https,不支持net.t ...

  10. node.js ----NPM使用介绍

    NPM 使用介绍 NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从 ...