【问题】
给定数组arr,arr中所有的值都为整数且不重复。每个值代表一种面值的货币,每种货币有无数张,再给定一个整数aim代表要找的钱数,求换钱的方法有多少种。
【基本思路】
这道题的经典之处在于它可以体现暴力递归、记忆搜索、动态规划之间的关系,并可以在动态规划的基础上再进行一次优化。
首先介绍暴力递归的方法。如果arr = [5, 10, 25, 1],aim = 1000,分析过程如下:
- 用0张5元的货币,让[10, 25, 1]组成剩下的1000,最终方法数记为res1。
- 用1张5元的货币,让[10, 25, 1]组成剩下的995,最终方法数记为res2。
- 用2张5元的货币,让[10, 25, 1]组成剩下的990,最终方法数记为res3。
…… - 用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