我目前正在尝试在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
答案 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
的硬币。这将确保解决方案不同。
此外,您还必须更改备忘录状态。您目前正在存储总和n
和size of array
(数组的大小在您提供的实现中没有变化,这与我提供的快速修复不同,因此它没有用!)作为备忘录的状态。现在,您将n
和lastUsedCoinIndex
一起确定备忘录状态。
修改强>
您的功能如下:
def coin_change(self,coin_array,n,lastUsedCoinIndex):
此处,唯一更改的变量是n
和lastUsedCoinIndex
。因此,您也可以修改构造函数,使其以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回答中的说明进行操作,并列出最初的数字列表。