博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 2844 多重背包
阅读量:4512 次
发布时间:2019-06-08

本文共 1706 字,大约阅读时间需要 5 分钟。

题目链接:

解题思路:

  这题实际上就是能否用所给硬币组合出某个价格,然后统计能组合出的价格的总数,然后每个硬币个数不一,所以很明显是多重背包。

    对于多重背包我们用二进制优化,也就是对 num 个 a 物品按二进制进行分组,分出的每一组看做一种物品,那么就转化为01背包了。所以这题也算是标准的模板题了,有个坑注意,题目中的M 可以为负数,小心。

 

代码:

#include 
#define MAXS 100016#define INF 0x3f3f3f3fusing namespace std;/* hdu 2844*/int n,m;//how many prices(form 1 to m) Tony can pay use these coins. //也就是算的是该价格能否被组合出来,统计能组合出来的价格的总数//有个坑点 m 可能为负值int value[102];int num[102];int f[MAXS];// 完全背包void competepack(int w,int v)//物重 价值{ for (int i=w;i<=m;++i) f[i] = max(f[i],f[i-w]+v);}//01 背包void onezeropack(int w,int v) // 01 背包{ for (int i = m;i>=w;i--) f[i] = max (f[i],f[i-w]+v);}void init()//这里必须是恰好装满背包才行。所以这样初始化而不是全初始化为0{ f[0] = 0; for (int i=1;i<=m;++i) f[i] = -INF;}int main (){ while( (2 == scanf ("%d%d",&n,&m) ) && n!= 0 && m!= 0 ) { init();//初始化 int ans = 0; //输入价值和个数 for (int i=0;i
0 ) for (int i=0;i
= m) //这是就相当于是个完全背包。超过了总容量,不就相当个数无限嘛 competepack(value[i],value[i]); else // 多重背包进行分组转化为01 背包 { //根据num[i]数目进行分组。 for (int k = 1; k < num[i]; k <<= 1 ) { onezeropack(value[i]*k,value[i]*k); num[i] -= k;//分组是按二进制,1,2,4,8... } if (num[i]) //如果最后分组还有剩 onezeropack(value[i]*num[i],value[i]*num[i]);//这一步是为了对最后剩下的num处理和当num==1时的处理 } } else { printf("%d\n", ans); continue; } for(int j = 1 ; j <= m ; ++j) if (f[j] > 0)//说明该容量的背包能被恰好装满,也就是该价格能由coins组合出来 ans++; //输出答案 if (ans) printf("%d\n", ans); } return 0;}

 

转载于:https://www.cnblogs.com/yuluoluo/p/8918571.html

你可能感兴趣的文章
APP压力稳定性测试
查看>>
Windows文件操作基础代码
查看>>
1-8
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_04-集合_04 数据结构_2_数据结构_队列
查看>>
Entity Framework操作Oracle数据库实现主键自增问题
查看>>
Leetcode WC-108-03 931-下降路径最小和
查看>>
从“智猪博弈”看所谓“大国责任”
查看>>
Day3:Spring-JDBC、事务管理
查看>>
模块的四种形式
查看>>
教你如何培养幽默感
查看>>
asp.net的一个简单简历缓存方法
查看>>
loj 1185(bfs)
查看>>
全排列-按从大到小-time limited
查看>>
减肥中,做个 体重三围 测量软件
查看>>
windows下命令行修改系统时间;修改系统时间的软件
查看>>
[LeetCode] 384. Shuffle an Array 数组洗牌
查看>>
最大公约数
查看>>
序列化和反序列化
查看>>
Mac上Chrome浏览器跨域解决方案
查看>>
Sublime Text 3 全程详细图文原创教程(持续更新中。。。)
查看>>