递归与动态规划---换钱的方法数

【问题】

  给定数组arr,arr中所有的值都为整数且不重复。每个值代表一种面值的货币,每种货币有无数张,再给定一个整数aim代表要找的钱数,求换钱的方法有多少种。

【基本思路】

这道题的经典之处在于它可以体现暴力递归、记忆搜索、动态规划之间的关系,并可以在动态规划的基础上再进行一次优化。

首先介绍暴力递归的方法。如果arr = [5, 10, 25, 1],aim = 1000,分析过程如下:

  1. 用0张5元的货币,让[10, 25, 1]组成剩下的1000,最终方法数记为res1。
  2. 用1张5元的货币,让[10, 25, 1]组成剩下的995,最终方法数记为res2。
  3. 用2张5元的货币,让[10, 25, 1]组成剩下的990,最终方法数记为res3。
    ……
  4. 用201张5元的货币,让[10, 25, 1]组成剩下的0,最终方法数记为res201。

那么res1 + res2 + res3 + …… +res201的值就是中的方法数。根据如上的分析过程定义递归函数process1(arr, index, aim)它的含义是如果用arr[index..N-1]这些面值的钱组成aim,返回总的方法数。最坏情况下时间复杂度为O(aim^N),N表示数组的长度。

下面是用python3实现的代码

#暴力递归方法
def coins1(arr, aim):
    def process1(arr, index, aim):
        if index == len(arr):
            return 1 if aim == 0 else 0
        else:
            res = 0
            for i in range(0, aim//arr[index]+1):
                res += process1(arr, index+1, aim-arr[index]*i)
        return res


    if arr == None or len(arr) == 0 or aim < 0:
        return 0
    return proc
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值