当前位置: 首页 > 知识库问答 >
问题:

递归变更生成算法

吕天逸
2023-03-14

给定目标金额和硬币面额列表,我的代码应该找到达到目标金额所需的最少硬币。

示例:

>

  • C(78,[1, 5, 10, 25, 50])=6

    • 我们可以从3x253x1做78,所以需要6个硬币

    C(48[1,7,24,42])=2

    • 48=2x24,因此2枚硬币就足够了

    C(35[1,3,16,30,50])=3

    • 我们可以从2x161x3中得到35,所以3个硬币就足够了

    我用for循环编写了代码,但如何使其递归

    def C(i, coins, cdict = None):
        if cdict == None:
            cdict = {}
        if i <= 0:
            cdict[i] = 0
            return cdict[i]
        elif i in cdict:
            return cdict[i]
        elif i in coins:
            cdict[i] = 1
            return cdict[i]
        else:
            min = 0
            for cj in coins:
                result = C(i - cj, coins)
                if result != 0:
                    if min == 0 or (result + 1) < min:
                        min = 1 + result
            cdict[i] = min
            return cdict[i]
    
  • 共有3个答案

    元胡媚
    2023-03-14

    因此,寻找动态编程实现的最佳场所是:交互式python

    然而,经过一点测试,我发现它不是最快的解决方案。它的好处是,一次运行就足以找到所有更改值的值。

    我最喜欢的还是在缓存中使用递归

    from collections import defaultdict
    from functools import lru_cache
    
    
    @lru_cache(maxsize=1024)
    def greedy(coin_list, change):
        if change in coin_list:
            return defaultdict(int, [(change, 1)])
        else:
            min_coins = change
            for c in [coin for coin in coin_list if coin < change]:
                result_min1 = greedy(coin_list, change - c)
                num_coins = 1 + sum(result_min1.values())
                if num_coins <= min_coins:
                    min_coins = num_coins
                    result = defaultdict(int, [(c, 1)])
                    for c1, n in result_min1.items():
                        result[c1] += n
            return result
    
    戚森
    2023-03-14

    尝试使用贪婪算法(首先是最大的硬币)。将硬币从列表中移除,然后应用总数,并从内部再次调用该函数。

    子车安和
    2023-03-14

    这是变革的问题。下面是标准的递归解决方案,V是硬币列表,C是目标金额:

    def min_change(V, C):
        def min_coins(i, aC):
            if aC == 0:
                return 0
            elif i == -1 or aC < 0:
                return float('inf')
            else:
                return min(min_coins(i-1, aC), 1 + min_coins(i, aC-V[i]))
        return min_coins(len(V)-1, C)
    

    这是一个优化版本,使用动态编程

    def min_change(V, C):
        m, n = len(V)+1, C+1
        table = [[0] * n for x in xrange(m)]
        for j in xrange(1, n):
            table[0][j] = float('inf')
        for i in xrange(1, m):
            for j in xrange(1, n):
                aC = table[i][j - V[i-1]] if j - V[i-1] >= 0 else float('inf')
                table[i][j] = min(table[i-1][j], 1 + aC)
        return table[m-1][n-1]
    

    这两种实现都将始终返回最佳解决方案,但对于大输入,第二种实现将更快。请注意,其他答案中建议的贪婪算法仅对某些货币组合给出了最优解,例如,它适用于美国硬币。

     类似资料:
    • 问题内容: 最近,我编写了一个函数来生成具有非平凡约束的某些序列。问题来自自然的递归解决方案。现在碰巧,即使对于相对较小的输入,序列也要成千上万,因此我宁愿使用我的算法作为生成器,而不是使用它来填充所有序列的列表。 这是一个例子。假设我们要使用递归函数计算字符串的所有排列。以下朴素算法采用一个额外的参数“存储”,并在找到一个参数时附加一个置换: (请不要在意效率低下,这只是一个例子。) 现在,我想

    • 我想做一个递归算法来解决做出改变的问题。是否可以使用非动态方法,不仅返回最小数量的硬币,还返回用于构成给定值的硬币集, 例如,给定值6和硬币组=[1,3,4]。有没有可能创建一个不记忆的递归算法,可以返回最小数量的硬币(2)和硬币集(3,3)? 编辑:这是我当前的算法,但它只返回硬币总数: 将返回3,但我希望它也提供集合{5,5,1}。第二个参数(2)是硬币的数量减去1。

    • 主要内容:递归的底层实现机制编程语言中,我们习惯将函数(方法)调用自身的过程称为 递归,调用自身的函数称为 递归函数,用递归方式解决问题的算法称为 递归算法。 函数(方法)调用自身的实现方式有 2 种,分别是: 1) 直接调用自身,例如: 2) 间接调用自身,例如: 程序中,function1() 函数内部调用了 function2() 函数,而 function2() 函数内部又调用了 function1() 函数。也就是

    • 对于二进制搜索树,我只能访问根节点,而我正在尝试编写一个递归方法来挖掘其左节点。 例如 root.left(); 成为 根左()。左(); 然后, 根左()。左(); 你看这是怎么回事...有没有递归的方法来更改/添加到变量中?

    • 本文向大家介绍c#递归生成XML实例,包括了c#递归生成XML实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了c#递归生成XML的方法。分享给大家供大家参考。具体实现方法如下: 这里结合网上搜到的资料,写了个递归生成xml,经过调试可以使用,数据库结构如下图所示: 代码如下: 希望本文所述对大家的C#程序设计有所帮助。

    • 问题内容: 我天真地尝试创建一个递归生成器。没用 这是我所做的: 我所得到的只是第一项。 有没有办法使这种代码起作用?本质上是在递归方案中将命令转移到以上级别吗? 问题答案: 尝试这个: 我应该指出,由于您的功能存在错误,因此无法使用。它可能应该包含不为空的支票,如下所示: