多重背包(二进制优化)模板

题意:

有n个硬币,每一个硬币有自己的数值Vi,其个数为Ci。不同硬币的不同组合能买到不同物品,问在1~V的区间内最多能买到多少不同种类的物品。

思路:

其实题意也就是求硬币在

[1,V]

[1 , V ] 区间能组合成多少不同数字。那么问题来了,怎么求出?

直接暴力求那是绝对不能做的,现在的比赛怎么存在这么简单的问题。

可以把它转化为背包问题,dp[i] 表示硬币组成i的钱能买最多多少钱的东西。我们能够用w钱买的东西的价值v 如果w == v 代表着我们可以用硬币买到这个东西,也就是能硬币能组合成w,为什么要w == v 呢?因为比如:dp[10] = 8, 意味着10块钱(区间范围是10)可以买到8块钱的东西,但是硬币无法组合为10,毕竟一分价钱一分货。

那么实现:如果某一种硬币本身的范围大于等于V,则可以当做完全背包问题来写。若然小于V,则二进制转化为0-1背包问题来写。

关于二进制转化:

字面意思是:某一个物品有c个,我们把c分解成二进制数字,而分解之后的数字能够完美表示小于等于c。
比如:c = 7 = 111(二进制), 可以把7分解为001,010,100,这三个数可以组合成小于等于7的正整数。

比如:c = 13 = 1101(二进制),可以分解为0001,0010,0100,和0110,其中前三个数字可以合成小于等于7的正整数,加上0110就可以表示8~13的任意数字。

具体实现:

int k = 1;
while(k <= cnt) {ZeroOnePack(k*val,k*w);cnt -= k;       //这里需要手动计算理解k *= 2;         //二进制分解
}
ZeroOnePack(cnt*val,cnt*w);     //上边c = 13的情况中6的由来。

#include <iostream>
#include <cstring>
#include <cstdio>using namespace std;const int maxn = 105;int n,V;
int dp[100005];
int v[maxn],c[maxn];void CompletePack(int value,int weight)
{for(int i = weight;i <= V; i++) {dp[i] = max(dp[i],dp[i-weight]+value);}
}void ZeroOnePack(int value,int weight)
{for(int i = V;i >= weight; i--) {dp[i] = max(dp[i],dp[i-weight] + value);}
}void solveOneCoin(int val,int w,int cnt)
{if(V <= val*cnt) {CompletePack(val,w);return ;}else {int k = 1;while(k <= cnt) {ZeroOnePack(k*val,k*w);cnt -= k;k *= 2;}ZeroOnePack(cnt*val,cnt*w);}
}int main()
{freopen("in.txt","r",stdin);while(scanf("%d%d",&n,&V) != EOF &&  n + V) {memset(dp,0,sizeof(dp));for(int i = 1;i <= n; i++) {scanf("%d",&v[i]);}for(int i = 1;i <= n; i++) {scanf("%d",&c[i]);}for(int i = 1;i <= n; i++) {solveOneCoin(v[i],v[i],c[i]);}int ans = 0 ;for(int i = 1;i <= V; i++) {if(dp[i] == i) {ans++;}}printf("%d\n",ans);}return 0;
}

HDU 2844 (多重背包)相关推荐

  1. hdu 3591 多重背包+完全背包练习题

    1 题目 http://acm.hdu.edu.cn/showproblem.php?pid=3591 题意:货币系统有 N 种不同面值的钱,每种钱的价值分别为 V1,V2,...,VN 一个人要买价 ...

  2. HDU 5445 (多重背包)

    题目链接:点击这里 题意: 有n个物品, m个卡车. 已知每种物品的能量, 体积和数量还有每种卡车的体积, 花费和数量, 求至少得到p能量的最少的卡车花费. 物品装卡车的时候能够切开装. 两次多重背包 ...

  3. hdu 2191 多重背包

    悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  4. hdu 2191 (多重背包二进制优化)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 实现代码: #include<bits/stdc++.h> using namespac ...

  5. hdu 2191 多重背包入门

    悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  6. HDU 2844 Coins 多重背包

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2844 Coins Time Limit: 2000/1000 MS (Java/Others)Mem ...

  7. HDU - 2844 Coins(多重背包+完全背包)

    题意 给n个币的价值和其数量,问能组合成\(1-m\)中多少个不同的值. 分析 对\(c[i]*a[i]>=m\)的币,相当于完全背包:\(c[i]*a[i]<m\)的币则是多重背包,考虑 ...

  8. HDU 2844 Coins (多重背包)

    题目链接 题意:Tony想要买一个东西,他只有n种硬币,每种硬币的面值为a[i],每种硬币的数量为c[i],要买的物品价值不超过m,输出1-m中有多少种价格Tony可以用硬币组合出来. 题解:多重背包 ...

  9. hdu 3732(01背包转多重背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3732 思路:这么大的数据,用01背包肯定会TLE的,01背包转多重背包..最多也就11*11=121件 ...

最新文章

  1. 【问题收录】Android Studio 2.2使用时出现问题总结
  2. 中英文最大AI模型世界纪录产生,大模型竞赛新阶段来了
  3. 全球及中国教育行业投资动态与发展决策建议报告2022版
  4. 学习之模块架构 DotNetNuke 6
  5. CF1415D:XOR-gun(异或)
  6. 【剑指offer】_17正则表达式的匹配
  7. [转载] python中set使用介绍
  8. Java:根据二叉树的前序,中序遍历构造二叉树
  9. take android,Protake
  10. ANSYS_APDL——实例002-模态分析
  11. python博弈论代码_科学网—两篇关于社交网络和博弈论的论文及源代码分享 - 陈俊东的博文...
  12. g7108 android5,三星G7108V移动4G版一键Root权限获取及USB驱动
  13. 深度学习基础之三分钟轻松搞明白tensor到底是个啥!看不懂的话我倒立洗头~~
  14. tlwdr5660间歇性掉线_tl-wdr7660无线掉线?tl-wdr7660路由不稳定怎么办?
  15. 群英荟萃 | UINO优锘科技ThingJS平台亮相华为开发者大会
  16. Windows10系统出现休眠后电脑屏幕黑屏无法唤醒解决办法
  17. mscorsvw.exe关闭方法
  18. CAD修复块中心点问题(网页版)
  19. 计算机应用技术班级介绍,【完满超级团支部】计算机应用技术20-4班开展“点燃青春之火,成就辉煌人生”班级演讲活动...
  20. c++ 中getch()的用法

热门文章

  1. QT eventFilter 事件监测
  2. 24 迷你图标免费下载
  3. 计算机网络信息中心博士毕业要求,科学网—关于东南大学计算机博士毕业条件 - 董仕的博文...
  4. 汽车显示屏服务器连接不上,行车记录仪能连接汽车中控显示屏吗
  5. 国际区号和电话号码剥离
  6. 方正台式计算机初始bios密码,方正台式计算机BIOS设置U盘启动
  7. 《Context Encoding for Semantic Segmentation》论文笔记
  8. win10笔记本电脑如何设置为合上盖子即锁屏?
  9. 科研工具-R-META分析与【文献计量分析、贝叶斯、机器学习等】多技术融合实践
  10. 企业人力资源管理师(四级)题集(理论+实操(计算题)+职业道德)