POJ 1742 Coins ( 经典多重部分和问题 && DP || 多重背包 )
题意 : 有 n 种面额的硬币,给出各种面额硬币的数量和和面额数,求最多能搭配出几种不超过 m 的金额?
分析 :
这题可用多重背包来解,但这里不讨论这种做法。
如果之前有接触过背包DP的可以自然想到DP数组的定义 ==> dp[i][j] 表示使用前 i 种硬币是否可以凑成面额 j 。
根据这样的定义,则一开始初始化 dp[0][0] = true 最后统计 dp[n][1 ~ m] 为 true 的数量即为答案
状态转移方程为 dp[i][j] |= dp[i-1][ j - k*val[i] ] ( k 表示取 k 个第 i 种硬币、val[i] 表示第 i 种硬币的面额 )
转移方程的意义不难理解,需要考虑当前的 dp[i][j] 可以从哪些状态转移而来,如下
使用第 i 种硬币刚好凑成 j 的值应当为上个状态( dp[i-1][] )合法的 j-val[i]、j-2*val[i]、j-3*val[i]....
故代码应当为一个如下所示的三重循环,但是复杂度较高无法通过这题.....
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; ; ]; int num[maxn], val[maxn]; int main(void) { int N, C; && C==)){ ; i<=N; i++) scanf("%d", &val[i]); ; i<=N; i++) scanf("%d", &num[i]); memset(dp, false, sizeof(dp)); dp[][] = true; ; i<=N; i++){ ; j<=C; j++){ ; k<=num[i] && k*val[i]<=j; k++){ dp[i][j] |= dp[i-][j-k*val[i]]; } } } printf(, dp[N]+C+, true)); } ; }
通常使用 dp 数组只记录布尔值是种浪费的做法,一般就去考虑在保证正确性的情况下改变 dp 含义记录更多信息去降低复杂度!
现将 dp 含义改变为 ==> dp[i][j] 表示用前 i 种硬币凑成 j 时第 i 种硬币最多还可以剩多少
挑战书上是直接给出了定义,但是我更乐于探寻这玩意是什么来的? 注:以下都是我自己的想法
想想上面的解法,好像会发现其实如果我当前考虑过 dp[i][j] = true 了,那么 dp[i][j+val[i]]、dp[i][j+2*val[i]]、dp[i][j+3*val[i]]... 应该都为 true
而枚举 j 的顺序也恰好是从小到大,所以必定会枚举到 dp[i][j+val[i]]、dp[i][j+2*val[i]]...,所以何不写成如下这样
; i<=N; i++){ ; j<=C; j++){ dp[j] |= dp[j-val[i]]; } }
运行了样例之后发现这样的做法得出的答案比标准答案更大!为什么?因为这样的做法没有考虑到数量,一种硬币的数量是有限的
所以当 j+k*val[i] 的 k 超过了规定数量的时候就会发生错误,使得一些本该为 false 的 dp 数组值变成了 true,所以我们需要记录数量!
复杂度为 O(n*m) 在 POJ 上跑了 2016MS
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; ; ]; int num[maxn], val[maxn]; bool fun(int x) { ) return true; return false; } int main(void) { int N, C; && C==)){ ; i<=N; i++) scanf("%d", &val[i]); ; i<=N; i++) scanf("%d", &num[i]); memset(dp, -, sizeof(dp)); dp[] = ; ; i<=N; i++){ ; j<=C; j++){ ) dp[j] = num[i]; ) dp[j] = -; ; } } printf(, dp++C, fun)); } ; }
POJ 1742 Coins ( 经典多重部分和问题 && DP || 多重背包 )的更多相关文章
- poj 1742 Coins(二进制拆分+bitset优化多重背包)
\(Coins\) \(solution:\) 这道题很短,开门见山,很明显的告诉了读者这是一道多重背包.但是这道题的数据范围很不友好,它不允许我们直接将这一题当做01背包去做.于是我们得想一想优化. ...
- hdu 2844 poj 1742 Coins
hdu 2844 poj 1742 Coins 题目相同,但是时限不同,原本上面的多重背包我初始化为0,f[0] = 1;用位或进行优化,f[i]=1表示可以兑成i,0表示不能. 在poj上运行时间正 ...
- 题解报告:hdu 2844 & poj 1742 Coins(多重部分和问题)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- poj 1742 Coins(dp之多重背包+多次优化)
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- POJ 1742 Coins(多重背包, 单调队列)
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- [POJ 1742] Coins 【DP】
题目链接:POJ - 1742 题目大意 现有 n 种不同的硬币,每种的面值为 Vi ,数量为 Ni ,问使用这些硬币共能凑出 [1,m] 范围内的多少种面值. 题目分析 使用一种 O(nm) 的 D ...
- POJ 1742 Coins 【多重背包DP】
题意:有n种面额的硬币.面额.个数分别为A_i.C_i,求最多能搭配出几种不超过m的金额? 思路:dp[j]就是总数为j的价值是否已经有了这种方法,如果现在没有,那么我们就一个个硬币去尝试直到有,这种 ...
- POJ 1742 Coins(多重背包) DP
参考:http://www.hankcs.com/program/cpp/poj-1742-coins.html 题意:给你n种面值的硬币,面值为a1...an,数量分别为c1...cn,求问,在这些 ...
- poj 1742 Coins (多重背包)
http://poj.org/problem?id=1742 n个硬币,面值分别是A1...An,对应的数量分别是C1....Cn.用这些硬币组合起来能得到多少种面值不超过m的方案. 多重背包,不过这 ...
随机推荐
- 深入理解java:1.1. 类加载器
从java的动态性到类加载机制 我们知道,Java是一种动态语言. 那么怎样理解这个“动态”呢? 或者说一门语言具备了什么特性,才能称之为动态语言呢? 对于java,我是这样理解的. 我们都知道J ...
- python深度学习培训概念整理
对于公司组织的人工智能学习,每周日一天课程共计五周,已经上了三次,一天课程下来讲了两本书的知识.发现老师讲的速度太快,深度不够,而且其他公司学员有的没有接触过python知识,所以有必要自己花时间多看 ...
- CentOS7编译安装sshpass过程
环境说明:centos 7 cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) 我的sshpass版本 sshpass-1.06. ...
- 通过QT查找Word中的关键字,并做高亮或删除操作
最近由于项目需要,要用QT操作Word文档.具体的工作需求:在指定的Word文档(*.doc文件/*.docx文件)中查找关键字,找到后做高亮操作或者直接删除操作,然后另存为到别的目录(表示这个文件被 ...
- Java并发编程:锁的释放
Java并发编程:锁的释放 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #839496;} Ja ...
- 获取IP地址的几种方法
根据ip获取地址的几种方法 1.调用新浪IP地址库 <script type="text/javascript" src="js/jquery.js"&g ...
- CentOS卸载lamp环境的步骤
学习PHP的时候需要在CentOS系统下安装lamp环境,安装容易卸载就没那么简单了,因为lamp由Apache.MySQL.PHP三个部分构成,需要逐个卸载,小编就给大家介绍下CentOS卸载lam ...
- 数学: HDU Co-prime
Co-prime Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Subm ...
- 一致性Hash算法(转)
一致性Hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1.平衡性(Balance):平衡性是指哈希的结果能够尽可能分布在所有的缓冲(Cache)中去,这样可以使得所有的缓 ...
- spark 在启动的时候出现JAVA_HOME not set
解决方法:在sbin目录下的spark-config.sh 中添加对应的jdk 路径,然后使用scp -r 命令复制到各个worker节点