修复我的算法中的备忘录以应对硬币变化挑战

时间:2018-01-02 10:37:10

标签: python algorithm recursion dynamic-programming

我知道有很多关于这个挑战的主题,但在标记为重复之前,请继续阅读。

需要找到所有不同的改变方法,给出一个硬币列表。 我写了一个有递归的解决方案,但效率非常低。我想添加memoization。我知道还有其他方法(例如here)来解决它,但是为了理解事情是如何运作的,我正在寻求你帮助解决我在 my 中找到的问题溶液

首先,这是代码:

 # logrotate -f /etc/logrotate.d/logstash
 # ls -l /usr/share/logstash/logs/
 total 36
 -rw-r--r-- 1 logstash logstash    17 Jan  2 10:16 logstash.log
 -rw-r--r-- 1 logstash logstash 10701 Jan  2 10:16 logstash.log.1

这将返回2个解决方案,并且打印语句显示解决方案是(5,5,5,5)和(10,10)。第三种可能的解决方案(10,5,5)不包括在内,因为密钥中已有10个。

那么,如何使用唯一的方式保存一个dict来达到某个目标,而不实际跟踪所有解决方案,这会破坏目的。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我认为你完全没有你的逻辑。您应该为每个金额收集解决方案。同样有意义的是同时使用ncoins进行记忆,同时只允许不大于当前硬币的硬币,以便不产生相同变化的排列:

from collections import defaultdict
d = defaultdict(dict)

def make_change(n, coins):
    # base cases
    if n < 0:
        return []  # no possible solution
    if n == 0:
        return [[]]  # one solution: empty list
    # recursion
    sols = []  # solutions are to be collected
    # make hashable memo key, and guarantee to start with the bigger coins
    tpl = tuple(sorted(coins, reverse=True))  
    if tpl not in d[n]:
         for c in tpl:
             # Only allow coins <= c for the recursion, not to get permutations
             # of the same change, e.g. [10, 5] and [5, 10]
             for sol in make_change(n-c, [x for x in tpl if x <= c]):
                 sols.append([c] + sol)
         d[n][tpl] = sols        
    return d[n][tpl]

>>> make_change(20, [10, 5])
[[10, 10], [10, 5, 5], [5, 5, 5, 5]]
>>> make_change(25, [10, 5])
[[10, 10, 5], [10, 5, 5, 5], [5, 5, 5, 5, 5]]
>>> make_change(30, [10, 5])
[[10, 10, 10], [10, 10, 5, 5], [10, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5]]
>>> make_change(27, [10, 5])
[]

答案 1 :(得分:0)

只是为了清除事情(无法评论 - 抱歉),行

c += make_change(n-i, [c for c in coins if c<=i])

允许递归中的下一个调用仅使用小于您在当前步骤中使用的硬币。如果您的硬币从最大到最小< 有序(如schwobaseggl答案),这是有道理的,否则会削减解决方案。你的情况发生了什么 - 是这样的:当计算d [10]时,因为使用的第一枚硬币是5,你就取消了使用价值10的硬币的选项,因此只得到一个改变10的解决方案 - a (5,5)改变。

为了便于调试,您应该打印整个(小)表'd',而不是在代码中间打印的所有参数。