【题解】Coins(二进制拆分+bitset)
【题解】Coins(二进制拆分+bitset)
俗话说得好,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)的更多相关文章
- poj 1742 Coins(二进制拆分+bitset优化多重背包)
\(Coins\) \(solution:\) 这道题很短,开门见山,很明显的告诉了读者这是一道多重背包.但是这道题的数据范围很不友好,它不允许我们直接将这一题当做01背包去做.于是我们得想一想优化. ...
- hdu 2844 coins(多重背包 二进制拆分法)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- BZOJ 2069: [POI2004]ZAW(Dijkstra + 二进制拆分)
题意 给定一个有 \(N\) 个点 \(M\) 条边的无向图, 每条无向边 最多只能经过一次 . 对于边 \((u, v)\) , 从 \(u\) 到 \(v\) 的代价为 \(a\) , 从 \(v ...
- HDU 4135:Co-prime(容斥+二进制拆分)
Co-prime Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- 2018.09.08 bzoj1531: [POI2005]Bank notes(二进制拆分优化背包)
传送门 显然不能直接写多重背包. 这题可以用二进制拆分/单调队列优化(感觉二进制好写). 所谓二进制优化,就是把1~c[i]拆分成20,21,...2t,c[i]−2t+1+1" role= ...
- HDU1059 二进制拆分优化多重背包
/*问你能不能将给出的资源平分成两半,那么我们就以一半为背包,运行多重背包模版 但是注意了,由于个数过大,直接运行会超时,所以要用二进制拆分每种的个数*/ #include<stdio.h> ...
- 【最短路】【dijkstra】【二进制拆分】hdu6166 Senior Pan
题意:给你一张带权有向图,问你某个点集中,两两结点之间的最短路的最小值是多少. 其实就是dijkstra,只不过往堆里塞边的时候,要注意塞进去它是从集合中的哪个起始点过来的,然后在更新某个点的答案的时 ...
- 【找规律】【二进制拆分】hdu6129 Just do it
给你数列a,问你对它作m次求前缀异或和之后的新数列是什么. 考虑a1对最终生成的数列的每一位的贡献,仅仅考虑奇偶性, 当m为2的幂次的时候,恰好是这样的 2^0 1 1 1 1 1 ... 2^1 1 ...
- [bzoj4300]绝世好题_二进制拆分
绝世好题 bzoj-4300 题目大意:题目链接. 注释:略. 想法: 二进制拆分然后用一个数组单独存一下当前答案即可. Code: #include <iostream> #includ ...
随机推荐
- 在Android中实现阴影效果
在Android L推出后,Google提出了全新的设计语言:材质设计.其中很重要的一点就是阴影效果的使用,你可以为每一个View设置一个elevation值,相当于除了x.y之外的z值,z值决定了阴 ...
- python局部变量与全局变量
name = "head first python"def what_happens_here(): print(name) 1 name = "pytho ...
- 第十八章 Python批量管理主机(paramiko、fabric与pexpect)
这个人的文章不错:http://lizhenliang.blog.51cto.com/all/7876557 转载:http://lizhenliang.blog.51cto.com/7876557/ ...
- ylb:SQL 系统函数
ylbtech-SQL Server: SQL Server-SQL 系统函数 SQL 系统函数 1,ylb:SQL 系统函数 返回顶部 -- ============================ ...
- 【重点突破】——Canvas技术绘制音乐播放器界面
一.引言 在用Canvas练习制作了验证码之后,还有一个用Canvas技术很综合的练习——制作音乐播放器.在做这个练习的过程中,还有一个重要的观察点,那就是理解Canvas的一大问题. 二.要求 点 ...
- CocoaAsyncSocket使用笔记
先去github的站点下载最新的包,然后先看看介绍. 写的比較具体了 https://github.com/robbiehanson/CocoaAsyncSocket/wiki/Intro_GCDAs ...
- 如何选择Haproxy和Nginx
对于做软负载,我们都知道主流的方案有LVS.Haproxy.Nginx!那么对于Haproxy和Nginx,我们如何选择呢?回答这个问题之前,我根据个人使用经验来讲下它们的特点! Haproxy特点 ...
- vue sync
1.使用vue cli建立工程 2.在APP.vue中: <template> <div class="details"> <myComponent ...
- MSComm串口类的使用 (程序设计)
参考文档:http://wenku.baidu.com/link?url=MLGQojaxyHnEgngEAXG8oPnISuM9SVaDzNTvg0oTSrrJkMXIR_6MR3cO_Vnh-gr ...
- DataTable列 基础处理
DataTable dt=new DataTable(); 新增列: dt.Columns.Add("ColumnsName"); 删除列: dt.Columns.Remove(& ...