在多重背包的直接拆分法中,个数为$c[i]$的物体被拆成$c[i]$种不同的物体

这样就使得物体的种类增加了很多,使得算法效率很低。

上述方法把$c[i]$拆成$c[i]$个1,于是任意选择可以表示出$1$到$c[i]$之间的所有数,从而达到多重背包的目的

想到,从$2^0,2^1,2^2,...,2^k$任意选择可以表示出$1$到$2^{k+1}-1$之间的所有数

于是就有了二进制拆分法

首先找到最大的$k$,使得$\sum_{i=0}^{k}2^i<=c[i]$

令$t=\sum_{i=0}^{k}2^i$,易知,上面$k+1$个数可以组成$1$到$t$之间的任何数

那$t+1$到$c[i]$之间的数怎么表示呢?

令$p=c[i]-t$,再拆出一个p,就可以了,理由如下:

$c[i]=p+t,c[i]-1=p+t-1...$依次类推

由于$1$到$t$已经被表示,所以这样一来$1$到$c[i]$之间的每个整数都可以被表示

具体来说,就是把数量为$c[i]$的物体分为$k+2$个,它们的体积分别为$2^0*v[i],2^1*v[i],...,2^k*v[i],p$

Code:

是$POJ1742Coins$的代码,虽然会TLE,就当打了个二进制拆分法的板子叭

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define Ri register int
 5 #define il inline
 6 #define mem(a,b) memset(a,b,sizeof(a))
 7 #define go(i,a,b) for(Ri i=a;i<=b;i++)
 8 #define yes(i,a,b) for(Ri i=a;i>=b;i--)
 9 using namespace std;
10 const int N=101,M=100001;
11 int n,m,t,p,ans,a[N],c[N];
12 bool f[M];
13 il void calc(int x)
14 {
15     t=1,p=0;
16     while(t<=x){t+=(t<<1);p++;}
17     t=x-t/3;p--;
18 }
19 int main()
20 {
21     while(scanf("%d%d",&n,&m)&&n)
22     {
23         mem(f,0);ans=0;
24         go(i,1,n)scanf("%d",&a[i]);
25         go(i,1,n)scanf("%d",&c[i]);
26         f[0]=1;
27         go(i,1,n)
28         {
29             calc(c[i]);
30             go(j,0,p)
31             {
32                 int q=1;if(j)q*=2;
33                 yes(k,m,a[i]*q)
34                 f[k]|=f[k-a[i]*q];
35             }
36             yes(k,m,t)f[k]|=f[k-t];
37         }
38         go(i,1,m)if(f[i])ans++;
39         printf("%d\n",ans);
40     }
41     return 0;
42 }

View Code

转载于:https://www.cnblogs.com/forward777/p/10993426.html

多重背包的二进制拆分法相关推荐

  1. 为了OFFER,菜鸟的我必须搞懂动态规划系列三个背包问题之多重背包(二进制优化方法)

    @Author:Runsen @Date:2020/9/17 多重背包有三层循环,如果数据非常的大,那么程序就会变得非常悲伤.在多重背包的问题,其实更多的是考查多重背包的二进制优化方法.学习二进制优化 ...

  2. 多重背包问题和“二进制拆分”

    预告:我用两年写的新书<算法竞赛>,已于2022年2月交给清华大学出版社,预计于2022年7月出版.<算法竞赛>是一本"大全",内容覆盖"基础-中 ...

  3. 【多重背包】二进制转换/ 其实有区别的--不全懂,会不放心的

    占坑... https://blog.csdn.net/qinzhenhua100/article/details/40350219 啊首先二进制这个,比如7可以化成1  10 100  完美表示.. ...

  4. Dividing(HDU 1059)(多重背包_二进制优化)

    题目链接: 题意:有价值分别为1,2,3,4,5,6的marbles(大理石)若干,问是否能使这些marbles平分.[marbles总数不超过2e4(很明显这是一个大常数,所以用二进制优化来做)] ...

  5. 多重背包的二进制优化(ybtoj-宝物筛选)

    文章目录 题目描述 解析 朴素算法 代码 二进制优化 代码 thanks for reading! 题目描述 解析 朴素算法 首先考虑朴素算法 把数量为num的物体拆成num个子物体 其价值与重量是原 ...

  6. 多重背包(二进制优化)

    问题概述:有一个容量为V的背包和n个物品,第i种物品最多有n[i]件可用,每件体积是w[i],求解将哪些物品装入背 包可使这些物品的价值尽可能接近V但不大于V(POJ1276) 输入样例:       ...

  7. 多重背包单调队列优化思路_动态规划入门——多重背包与单调优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第14篇文章,也是动态规划专题的第三篇. 在之前的文章当中,我们介绍了多重背包的二进制拆分的解法.在大多数情况下,这种 ...

  8. 动态规划入门——多重背包与单调优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第14篇文章,也是动态规划专题的第三篇. 在之前的文章当中,我们介绍了多重背包的二进制拆分的解法.在大多数情况下,这种 ...

  9. ACwing 5. 多重背包问题 II(二进制拆分+DP)

    文章目录 1. 题目 2. 解题 1. 题目 有 N 种物品和一个容量是 V 的背包. 第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi. 求解将哪些物品装入背包,可使物品体积总和不超过 ...

最新文章

  1. mysql导入指定数据库_从mysql全备 导入指定数据库的数据:三种考虑方法
  2. C#基础——密码加密
  3. 图像处理之opencv图像特效大全
  4. java西游记壹_岩浆数码再现手机RPG游戏--西游记壹
  5. Openssl证书管理
  6. 第二十七篇 导航栏和内容块
  7. Python中np.sum()对axis的个人理解,超详细
  8. mysql 并发_mysql 的读写锁与并发控制
  9. 【DevOps】做个愉快的DevOps之XenServer自动化管理(1)
  10. 计算机操作系统(汤小丹)慕课版课后题答案第五章:储存器管理
  11. linux怎么增加用户账号,linux怎么添加用户
  12. 人工智能——深度学习
  13. 分布式架构中的八大谬误
  14. android的listview分组显示的时候layout_marginTop失效的解决办法
  15. 解题:POI 2008 Plot purchase
  16. 马斯克的推特CEO继任者曝光:带着老婆孩子睡公司,钢铁侠20年嫡系,现在掌舵挖洞公司...
  17. Banana Pi BPI-R2 Pro 开源路由器采用瑞芯微Rockchip RK3568芯片方案设计
  18. wlan测试仪软件,MT8860C WLAN 测试仪
  19. 线性代数让我想想:三阶行列式计算优化策略
  20. 【攻破html系列——第二天】网页结构

热门文章

  1. 一键抠图Portrait Matting人像抠图 (C++和Android源码)
  2. xshell免费版绿化版下载
  3. transformers中GLUE各个任务所用的评估方法
  4. 《零基础学C语言》前言
  5. python爬取js_Python爬取javascript(js)动态网页
  6. 【iOS】—— 高德地图SDK基础使用
  7. 欧美剧集观看最佳索引 US SHOWS GUIDE 【2005-12-27 转verycd】
  8. Windows控制台基本操作命令
  9. activiti+app+mysql_SpringBoot Activiti6系列教程(一)-activiti-app部署
  10. 计算机图形学习课后习题解答--孔令得版