poj 1276 Cash Machine 多重背包
来源:互联网 发布:linux创建多级文件夹 编辑:程序博客网 时间:2024/06/05 16:24
传送门:poj 1276 Cash Machine
题目大意
有各种不同面值的货币,每种面值的货币有不同的数量,请找出利用这些货币可以凑成的最接近且小于等于给定的数字cash的金额。
输入的前两个数表示背包容量,第二个数字表示有N种货币
接下来的N组两个数。第一个数表示货币数量,第二个数表示货币的价值
输出最接近并且小于等于背包容量的价值。
解题思路
在理解的01背包的基础上, 完全背包
,指每个物品有无限多个。 多重背包
,指每个物品的数量是有限的。当然,这时的问题不再是拿与不拿,而是拿多少的问题,当然不能超过背包容量。
状态转移方程为:dp( i,j ) = Max( dp( i-1, j ), dp( i-1, j-k*w[i]) + k*v[i] ) ( 0 <= k <= c/ w[i] )
.
看到这方程中有三个变量,最普遍的思想就是三层循环依次遍历i,j,k。但是这种如果数据的范围过大的时候就很容易超时了。
我们一般会采用一种方法就是二进制压缩
。将原来的物品按照2的n次方进行重新组合。用1、2、4、8…进行组合,可以组合出任意的数字。
AC代码
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int main(){ int n,amount; int num,deno; int dp[100005]; int value[100005]; while(scanf("%d%d",&amount,&n)!=EOF) { int cnt = 1; memset(dp,0,sizeof dp); for(int i=1;i<=n;i++) { scanf("%d%d",&num,&deno); for(int j=1;j<=num;j*=2)//二进制压缩 { value[cnt++] = j*deno; num-=j; } if(num>0) value[cnt++] = num * deno; } //如果不懂画一个二维表就差不多能懂了 for(int i=1;i<cnt;i++) { for(int j = amount;j>=value[i];j--) dp[j] = max(dp[j],dp[j-value[i]]+value[i]); } printf("%d\n",dp[amount]); } return 0;}
1 0
- POJ 1276 Cash Machine(多重背包)
- poj 1276 Cash Machine(多重背包+倍增)
- poj 1276 Cash Machine(多重背包)
- POJ 1276 Cash Machine (多重背包)
- poj 1276 Cash Machine (多重背包)
- poj 1276 Cash Machine----多重背包
- POJ 1276 Cash Machine (多重背包)
- POJ 1276 Cash Machine 多重背包
- 多重背包 poj 1276 Cash Machine
- 【POJ】1276 Cash Machine(多重背包)
- 【DP|多重背包】POJ-1276 Cash Machine
- poj 1276 Cash Machine(多重背包)
- POJ 1276 Cash Machine【多重背包DP】
- poj 1276 Cash Machine (多重背包)
- POJ 1276 Cash Machine(多重背包)
- poj 1276 Cash Machine(多重背包)
- poj 1276 Cash Machine (多重背包)
- poj 1276 Cash Machine (多重背包)
- 表单填写 大气的全屏形式概念表单(精)
- centos7 安装 mariadb(mysql的一个分支) 的正确命令
- Git9--从远程库克隆
- Simulator 慢动作问题
- SpringMVC访问静态资源的三种方式
- poj 1276 Cash Machine 多重背包
- Git10--分支管理
- 组合补考的我且先装个比,竞赛图中求汉密尔顿圈算法设计
- poj 3020 二分图
- 凸优化笔记(三)--凸函数
- Android 热修复 - AndFix 使用心得
- displaytag 中文问题 探索日志 注释
- Git11--创建与合并分支
- C语言面试之CPU控制