Python 用m个硬币兑换n美元

Python 用m个硬币兑换n美元,python,algorithm,debugging,Python,Algorithm,Debugging,我正在尝试实现以下问题的解决方案: 给定一个美元数n和一个m的美元值列表 不同的硬币,找到和打印的不同方式,你可以 如果每一枚硬币都有一个无限大的空间,可以兑换n美元 数量 完整的问题陈述是 在提出我的解决方案之前,我应该说,我知道动态规划可能是解决这个问题的最佳方法。我提出的解决方案不使用动态规划,我知道它远不是最有效的解决方案。然而,据我所知,这是正确的 问题是我的解决方案低估了做出改变的方法的数量。例如,给定n=75和{25 10 11 29 49 31 33 39 12 36 40 22

我正在尝试实现以下问题的解决方案:

给定一个美元数n和一个m的美元值列表 不同的硬币,找到和打印的不同方式,你可以 如果每一枚硬币都有一个无限大的空间,可以兑换n美元 数量

完整的问题陈述是

在提出我的解决方案之前,我应该说,我知道动态规划可能是解决这个问题的最佳方法。我提出的解决方案不使用动态规划,我知道它远不是最有效的解决方案。然而,据我所知,这是正确的

问题是我的解决方案低估了做出改变的方法的数量。例如,给定
n=75
{25 10 11 29 49 31 33 39 12 36 40 22 21 16 37 8 18 4 27 17 26 32 6 38 2 30 34}
作为硬币值,解决方案在返回16694时返回182。不过,它似乎适用于较小的测试用例

def make_change(coins, n):    
    solns = 0
    num_coins = len(coins)
    for i in range(num_coins):
        solns = solns + make_change_rec(coins, n-coins[0], coins[0])
        
        # We've found all solutions involving coin. Remove it
        # from consideration
        coins.pop(0)
    
    return solns

def make_change_rec(coins, n, parent):
    # If n == 0 we've found a solution
    if n == 0:
        return 1
    
    solns = 0
    # For each coin
    for coin in coins:
        # If coin > n, can't make change using coin
        if coin > n or coin < parent: # coin < parent rule ensures we don't count same solution twice
            continue
            
        # Use the coin to make change 
        solns = solns + make_change_rec(coins, n-coin, coin)
        
    return solns  
def兑换(硬币,n):
solns=0
硬币数量=len(硬币)
对于范围内的i(num_硬币):
solns=solns+make_change_rec(硬币,n-硬币[0],硬币[0])
#我们已经找到了所有涉及硬币的解决方案。移除它
#出于考虑
硬币。流行音乐(0)
返回solns
def更改记录(硬币、n、父项):
#如果n==0,我们找到了一个解决方案
如果n==0:
返回1
solns=0
#每一枚硬币
对于硬币中的硬币:
#如果硬币>n,则无法使用硬币进行更改
如果coin>n或coin

有人能帮我理解我做错了什么吗?我使用的是Python 3。

我认为您需要做的唯一更改是对
硬币
数组进行排序。现在你的递归肯定会耗尽时间。所以我建议您使用经典的动态规划

def make_change(coins, n):
    dp = [1] + [0] * n
    for coin in coins:
        for i in range(coin, n + 1):
            dp[i] += dp[i - coin]
    return dp[n]

我认为您需要做的唯一更改是对
硬币
数组进行排序。现在你的递归肯定会耗尽时间。所以我建议您使用经典的动态规划

def make_change(coins, n):
    dp = [1] + [0] * n
    for coin in coins:
        for i in range(coin, n + 1):
            dp[i] += dp[i - coin]
    return dp[n]

您需要在输入硬币之前对其进行排序。如果您的递归对于较大的值运行缓慢(它会),您可以像这样添加备忘录:

from functools import lru_cache

#leave your function as it is, but add this:
@lru_cache(maxsize=None)
def make_change_rec(coins, n, parent): 

您需要在输入硬币之前对其进行排序。如果您的递归对于较大的值运行缓慢(它会),您可以像这样添加备忘录:

from functools import lru_cache

#leave your function as it is, but add this:
@lru_cache(maxsize=None)
def make_change_rec(coins, n, parent): 

您确认过这个号码吗?
16694
以及如何确认?这有什么公式吗@ADAMH您确认过这个号码吗
16694
以及如何确认?这有什么公式吗@AdamCan您能否提供一个示例,说明如果我不对硬币数组进行排序,解决方案将如何中断?如果我运行您的代码而不对硬币进行排序,我将得到182作为答案(使用您的测试用例)。如果我对硬币进行排序并运行您的代码,我将得到16694。您自己已经声明第二个是正确的。您能否提供一个示例,说明如果我不对硬币数组进行排序,解决方案将如何中断?如果我运行您的代码而不对硬币进行排序,我得到182作为答案(使用您的测试用例)。如果我对硬币进行排序并运行您的代码,我得到16694。你自己说第二个是正确的。你能提供一个例子,说明如果我不对硬币数组进行排序,解决方案将如何崩溃吗?@Adam使用你之前发布的相同案例(n=75),对吗,所以问题是,在我计算所有涉及的解决方案之前,我可能会移除一枚硬币,因为硬币<父条件。你能提供一个例子,说明如果我不对硬币数组进行排序,解决方案将如何中断吗?@Adam使用了你之前发布的相同案例(n=75),对吗,所以问题是,在我计算所有的解之前,我可能会移除一枚硬币,因为硬币<父条件。