递归给出了最小硬币变化的正确答案,但动态编程给出了错误的答案

时间:2016-02-02 00:21:05

标签: python recursion dynamic-programming

我试图在几个小时内解决这个问题,但我无法直观地思考它。对此有一种心理障碍。经过多次尝试,我能够在存在解决方案的情况下获得正确的递归解决方案。所以我有以下问题:

  1. 递归程序为存在解决方案的输入提供了正确的解决方案。如何退货'没有解决方案'解决方案不存在的地方。硬币的前[3,10],变更没有解决方案17。

  2. DP程序有什么错误?我尝试使用memoization技术,我创建了一个字典并为其添加了值,但程序运行不正常。

  3. IUnknown

    现在这是DP解决方案。

    import math
    def findMinCoins(denomination, change):
        #recursive solution
        minCoins = change
        if(len(denomination )== 0 or change ==0): #when there are no coins or change is 0
            return 0
        elif(change in denomination):
            return 1
        elif(change < min(denomination)):
            return float("inf")
        else:
            for i in denomination:
                if(i<=change):
                    numCoins = 1 + findMinCoins(denomination, change - i)
                    if(numCoins < minCoins):
                        minCoins = numCoins
        return minCoins
    
    c = [3,10]
    d = 30
    
    print findMinCoins(c,d)
    

1 个答案:

答案 0 :(得分:0)

问题在于您使用备忘录的方式。如果您找到了针对特定变更量的解决方案,那么您永远不会认为可能有更好的解决方案。看一下逻辑

    if (coinsDict.get(change)):
        print 'dictionaty',change, coinsDict.get(change)
        return coinsDict[change]
    elif(i<=change):
        numCoins = 1 + findMinCoins(denomination, change - i)

在你第一次通过递归时,你一直向下走,发现你可以用10个硬币的3个硬币处理30美分。然后你放松回到堆栈的顶部,然后用10美分一块再试一次......但在您懒得寻找解决方案之前,上述逻辑说,&#34;我已经知道如何处理30美分:返还10个硬币。&#34;它永远不会探索涉及其他金额的解决方案。

如果您颠倒检查面额的顺序,您将获得所需的解决方案。确保您尝试其他测试用例:您应该发现这个简单的修复不足以修复您的逻辑。例如,尝试

c = [3,11,13] d = 22

如果你没有找到更好的解决方案,你会发现13,3,3,3的4钱解决方案,并且错过11,11答案。