找零问题之递归算法求解改进
写在前面,一定要弄清楚,字典的传递传的是引用,是地址!,这个小问题浪费了我将近两个小时。等号复制,dict.copy()和copy模块的deepcopy()方法,这三个要搞清楚。
前面提到了递归方法解决找零问题,但是当数值非常大,或者纸币面值种类很多时,程序跑起来就会花费很多时间。我的笔记本配置比较低,面值[1,5,10,25]的,找零63元,需要5分钟所有的时间。其实可以想象,这种递归非常浪费时间。
比如拿上一篇文章中的17元来说,简单说一下
可以分成一张10元和找零7元的最优解
也可以分成1张5元和找零12元的最优解,而找零12元必定能分成一张5元和找零7元的最优解(当然也能是5张一元和找零7元的最优解)
也可以分成1张2元和找零15元的最优解,而找零15元的必定能分出来找零7元的最优解。
也可以分成一张1元和找零16元的最优解,而找零16元也必定能分出找零7元的最优解。
所以有很多重复计算,造成了巨大的时间开销。
可以在计算的过程中保存子问题的最优解,需要用到的时候先查表,有则取出来,无则计算并存表。
这里我用了两个表,一个是存储纸币数量,另一个是存储对应数量的纸币方案字典。(一定要注意,字典传递的是引用,对字典进行修改时需要“复制”一份)
def recMC(coinList, change, knowResults, knowD