Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 换币递归解卷算法_Algorithm_Recursion_Recursive Datastructures - Fatal编程技术网

Algorithm 换币递归解卷算法

Algorithm 换币递归解卷算法,algorithm,recursion,recursive-datastructures,Algorithm,Recursion,Recursive Datastructures,我正在尝试解除此算法中的递归函数。硬币兑换问题:给定一个目标数量n和一个不同硬币值的列表数组,兑换数量所需的最少硬币是多少 def rec_coin(target,coins): # Default to target value min_coins = target # Check to see if we have a single coin match (BASE CASE) if target in coins: return 1

我正在尝试
解除
算法中的
递归
函数。硬币兑换问题:给定一个目标数量n和一个不同硬币值的列表
数组
,兑换数量所需的最少硬币是多少

def rec_coin(target,coins):

    # Default to target value
    min_coins = target

    # Check to see if we have a single coin match (BASE CASE)
    if target in coins:
        return 1

    else:

        # for every coin value that is <= than target
        for i in [c for c in coins if c <= target]:

            # Recursive Call (add a count coin and subtract from the target) 
            num_coins = 1 + rec_coin(target-i,coins)

            # Reset Minimum if we have a new minimum
            if num_coins < min_coins:

                min_coins = num_coins

    return min_coins

# rec_coin(63,[1,5,10,25])
# 6

为什么我们需要添加1?取消递归的正确方法是什么?您提供的代码效率很低。为了找到63的解,假设它将首先以最小硬币(即1)的步数递归到目标量。然后,在多次回溯和尝试使用其他硬币后,它最终回溯到最外层,并尝试使用价值为5的硬币。现在递归又开始了,就像以前一样,增加了值为1的硬币。但问题是,这个中间值(63-5)之前已经被访问过(在选择硬币1后深入5层),并且需要大量函数调用才能得到该值的结果。然而,算法将忽略这一点,并再次执行所有这些工作

一个常见的解决方案是动态规划,即记忆早期发现的解决方案,以便无需额外工作即可重用

我将在这里介绍一种自下而上的方法:它首先检查仅用一枚硬币就能获得的所有金额。这些金额被放入一个队列中。如果目标在其中,那么答案是1。如果不是,则通过将所有可能的硬币添加到每个硬币来处理队列中的所有金额。有时会发现一个以前已经访问过的值,在这种情况下,它不会被放入下一个队列,但在其他情况下会被放入下一个队列。如果现在目标值在该队列中,您知道只需2枚硬币即可达到目标

这个过程在一个循环中继续,这实际上只是树中的广度优先搜索,其中数量是节点,边表示通过向其中添加一枚硬币可以从另一个数量中获得一个数量。搜索从表示0的数量的节点开始

下面是它的代码:

def rec_硬币(目标,硬币):
visited=set()#我们已经用最少数量的硬币获得的金额
金额=[0]#使用相同数量硬币的最新金额系列
对于范围(1,目标+1)内的min_硬币:
下一步金额=[]
以金额表示的金额:
对于硬币中的硬币:
添加=金额+硬币
如果添加==目标:
归还民币
如果未在访问中添加:
已访问。添加(已添加)
下一步金额。追加(已添加)
金额=下一笔金额
印刷品(rec_硬币(63[1,5,10,25]))
1 + 63-1 coins + 62-1 + 61-1 and so on..