我们有不同数量的无限制硬币-计算这些硬币如何构成特定数量的独特组合。例如:
n = 4(例如4美分)
coins_list = [1,2]-我们有1美分硬币和2美分硬币 不同的组合是112、1111和22。(应该排除121和211,因为它们不是唯一的-使用一个2美分硬币和两个1美分硬币)
我已经观看了以下视频:https://www.youtube.com/watch?v=k4y5Pr0YVhg 无数次,并且编辑了无数次代码,但我无法摆脱不同订单的相同组合。
def make_change(n, coinlist_index=None):
coin_list = [1, 2]
if coinlist_index == None:
coinlist_index = 0
#coin index position in coin_list; starts at index 0 and cycles through all the coins
if n == 0:
return 1
if n < 0:
return 0
ways = 0
# if I use for i in range(len(coin_list)), it returns an error message saying that index is out of range
for coinlist_index in range(len(coin_list)):
ways += make_change((n - coin_list[coinlist_index]), coinlist_index)
coinlist_index += 1
return ways
make_change(4)
输出: 5
我的输出是5(用1美分硬币和2美分硬币进行4美分兑换的不同方法),而不是3(这是我想要的)。
我确定它与for循环到底有关,但是当我将“ for range的coinlist_index ...”更改为另一个迭代器时,我得到一个错误,指出索引超出范围
发生了什么,更重要的是,我该如何解决?
编辑:PS这只是我要解决实际分配的一个简单示例-包含6种类型的硬币(以美分(1、5、10、25、50、100)为单位),并计算制作多少种方法换200美元。我已经看到并尝试了动态编程方法,该方法行得通,但是我们必须使用递归进行分配。
答案 0 :(得分:0)
我认为5实际上是正确的答案。
1 1 1 1
1 1 2
1 2 1
2 1 1
2 2
或者,如果要获得不同的结果,可以将结果存储在列表中,然后删除重复的结果。
def make_change(n, coinlist_index=0):
coin_list = [1, 2]
if n == 0:
return [[]]
if n < 0:
return []
ways = []
for coinlist_index in range(len(coin_list)):
res = make_change((n - coin_list[coinlist_index]), coinlist_index)
ways += list(map(lambda x : x + [coin_list[coinlist_index]], res))
return ways
def remove_dup(lolist):
res = []
for lst in lolist:
lst.sort()
if lst not in res:
res.append(lst)
return res
print remove_dup(make_change(4))
答案 1 :(得分:0)
好像我可以正常工作了。在每个递归遍历中,您都希望确保您不会重复计算进行更改的可能方法。我这样做的目的是确保您永远不会在coin_list中倒退。因此,对于coin_list [1,2],如果我们曾经使用过2美分的硬币,那么我们永远都不希望以后再使用1美分的硬币。我通过稍微更改for循环来确保遵循此顺序:
for i in range(len(coin_list)-coinlist_index):
ways += make_change((n - coin_list[i+coinlist_index-1]), coinlist_index)
在for循环中,我从上限减去了coinlist_index,因此一旦索引达到1,我们就不会循环遍历所有硬币,然后将索引添加到您从coin_list中拉出的位置,确保一旦coinlist_index为1或更大,我们从不使用coin_list [0]。这使我在您的示例案例中达到3,希望它适用于所有案例。完整代码:
def make_change(n, coinlist_index=None):
coin_list = [1, 2]
if coinlist_index == None:
coinlist_index = 0
#coin index position in coin_list; starts at index 0 and cycles through all the coins
if n == 0:
return 1
if n < 0:
return 0
ways = 0
# if I use for i in range(len(coin_list)), it returns an error message saying that index is out of range
for i in range(len(coin_list)-coinlist_index):
ways += make_change((n - coin_list[i+coinlist_index-1]), coinlist_index)
coinlist_index += 1
return ways
print(make_change(4))