Python硬币改变动态编程

时间:2017-09-16 19:24:50

标签: python dynamic-programming coin-change

我目前正在尝试在Python中实现动态编程,但我不知道如何设置回溯部分以使其不重复排列。 例如,输入将是(6,[1,5])并且预期输出应该是2,因为有2种可能的方式来排列1和5,使得它们的总和等于6.这些组合是{1,1 ,1,1,1,1}和{1,5}但我的程序目前的工作方式,它考虑了上面显示的组合和组合{5,1}。这导致输出为3,这不是我想要的。所以我的问题是“如何防止重复排列?”。我目前的代码如下所示。

    import collections as c

    class DynamicProgram(object):
        def __init__(self):
            self.fib_memo = {}
            # nested dictionary, collections.defaultdict works better than a regular nested dictionary
            self.coin_change_memo = c.defaultdict(dict)
            self.__dict__.update({x:k for x, k in locals().items() if x != 'self'})
        def coin_change(self, n, coin_array):
            # check cache
            if n in self.coin_change_memo:
                if len(coin_array) in self.coin_change_memo[n]:
            return [n][len(coin_array)]

            # base cases
            if n < 0: return 0
            elif n == 1 or n == 0: return 1

            result = 0
            i = 0

            # backtracking (the backbone of how this function works)
            while i <= n and i < len(coin_array):
                result += self.coin_change(n-coin_array[i], coin_array)
                i += 1

            # append to cache
            self.coin_change_memo[n][len(coin_array)] = result

            # return result
            return result

2 个答案:

答案 0 :(得分:0)

快速修复:

result += self.coin_change(n-coin_array[i], coin_array[i:]) # notice coin_array[i:] instead of coin_array

但是每次创建新列表时都要避免这种情况。

更好的解决方法是:

只需在函数中添加参数lastUsedCoinIndex即可。然后始终使用硬币数组中index&gt; = lastUsedCoinIndex的硬币。这将确保解决方案不同。

此外,您还必须更改备忘录状态。您目前正在存储总和nsize of array(数组的大小在您提供的实现中没有变化,这与我提供的快速修复不同,因此它没有用!)作为备忘录的状态。现在,您将nlastUsedCoinIndex一起确定备忘录状态。

修改

您的功能如下:

def coin_change(self,coin_array,n,lastUsedCoinIndex):

此处,唯一更改的变量是nlastUsedCoinIndex。因此,您也可以修改构造函数,使其以coin_array作为输入,然后您将访问构造函数通过self.coin_array初始化的coin_array。那么函数将变得简单:

def coin_change(self,n,lastUsedCoinIndex):

答案 1 :(得分:0)

避免排列的一种方法是使用&#34;非减少&#34;中的数字。订购。通过这样做,你永远不会为[5 1]添加答案,因为它不在&#34;非减少&#34; order.And [1 5]将被添加到&#34;非减少&#34;顺序。

因此,如果您修改了以排序顺序使用第i个数字,那么代码中的更改将是您永远不会使用严格低于此值的数字。

代码更改将按照Suparshva's回答中的说明进行操作,并列出最初的数字列表。