今天上算法课的tutorial,主要是讲贪婪算法。老师在课上提到了canonical coins system,但并没有深入讲解。回来看了一篇论文,整个问题很有意思,写下来记录一下。
引入
以中国为例,我们的货币系统中,有1角,5角,1元,5元,10元,20元,50元,100元这几种面值。我们的目的是,当给定一个需要找零的值,我们要用最少的货币数量来组合成这个值。用什么策略能达到这个目的?贪婪算法是否对每一种货币系统都有最优解?这是要讨论的问题。
这是一个NP-hard问题,但是在大多数国家所使用的货币系统中,贪婪算法是会起作用的。即先拿最大的面值去匹配,然后拿第二大的…但是得到的基本上都不是最优解。举个例子,一个货币系统中的基础面值有{1, 3, 4},如果想要拿出6块。使用贪婪算法会拿出一张4和两张1,这是三张钞票,但实际上最优解是两张3。
什么是Canonical coins system
贪心和动态规划都可以解决这个问题,只不过在时间复杂度和所得结果上需要权衡
- 贪心:贪心算法的基本思想是优先选择面值最大的硬币,直到组合成所需金额。贪心表示的优点是算法简单,计算速度快,但不一定能够得到最少的硬币数。
- 动态规划:优点是准确性高,但算法复杂度较高。因为它要求对所有可能的状态进行计算和记录,需要消耗大量的计算和空间资源。
详细说一下
- 给定一个货币系统的面值集合,是一个向量C=( c 1 , c 2 , c 3 , . . . , c n c_1, c_2, c_3, ..., c_n c1,c2,c3,...,cn)
- 给定一个系数集合,也是一个向量V=( v 1 , v 2 , v 3 , . . . , v n v_1, v_2, v_3, ..., v_n v