展开全部
choices = [1, 5, 16, 23, 33]
cache = {}
def f(x):
if x in cache: # 注2
return cache[x]
if x > 5: # 注1
ch = [5, 16, 23, 33]
#elif x > 80:
# ch = [16, 23, 33]
else:
ch = choices
l = [x - c for c in ch if x >= c]
if all(l): # 都为真,也就是还有零钱
cache[x] = min([f(x1) for x1 in l]) + 1
else:
cache[x] = 1
return cache[x]
算法思路来自跟你问同样问题的另一个楼里,那边给了个循环的算法,e68a843231313335323631343130323136353331333332636431说实话看不懂... 还是递归的好理解点;
最开始的版本是不带两个注解的地方;效率狂差,99都算不动了
注解1
开始想应该是递归的时候无用的计算太多,想了半天,考虑到金额较大的时候,就不用考虑小面额的,所以加了判断;但是这个排除的依据到底该是多少呢?大于5元的,就先不考虑1元了这个比较显然,后面的呢?感觉应该是取最小公倍数,但是证明不出来...
不过即使这样,也只是对不到200的数有明显改善,效率还是很差
注解2
后来想了下,在这过程中,就是针对不同的x 计算f(x),存在多次重复,对同样的x,f(x)的结果应该是一样的,所以加了一个cache缓存计算结果,这下效果很明显了