【问题标题】:dynamic programming coin change that return an array返回数组的动态编程硬币变化
【发布时间】:2019-04-13 01:30:33
【问题描述】:

我正在尝试获取目标金额总和的所有硬币。我能够获得所需的硬币数量。我将如何解决它。

您可以无限使用相同的硬币 例如。 change([2], 10) => [2, 2, 2, 2, 2]

def change(coins, amount):
    result = [amount+1] * (amount+1)

    result[0] = 0

    for i in range(1, amount+1):
        for coin in coins:
            if i >= coin:
                result[i] = min(result[i], result[i-coin] + 1)

    if result[amount] == amount+1:
        return -1

    return result[amount]

change([1, 2, 5,8], 7) => [5, 2] 顺序无关紧要。

【问题讨论】:

  • 请更详细地解释您想要发生的事情。
  • 你想要动态规划的所有结果还是最好的结果?如果你想要所有结果,动态规划在这里不起作用。

标签: python dynamic-programming


【解决方案1】:

如果你使用dyanmic programming你只能得到最好的结果,你可以通过一个数组来存储dynamic programming的中间结果,我已经根据你的dp版本进行了修改:

def change(coins, amount):
    result = [amount+1] * (amount+1)
    coins_results = [[] for _ in range(amount+1)]

    result[0] = 0

    for i in range(1, amount+1):
        for coin in coins:
            if i >= coin and result[i - coin] + 1 < result[i]:
                result[i] = result[i-coin] + 1
                coins_results[i] = coins_results[i-coin] + [coin]

    if result[amount] == amount+1:
        return []

    return coins_results[amount]

测试:

print(change([1, 2, 5, 8], 7))
print(change([2], 10))

输出:

[5, 2]
[2, 2, 2, 2, 2]

这是一个通过backtracking输出所有结果的版本:

def change(coins, amount):
    res = []

    def backtrack(end, remain, cur_result):
        if end < 0: return
        if remain == 0:
            res.append(cur_result)
            return
        if remain >= coins[end]:
            backtrack(end, remain - coins[end], cur_result + [coins[end]])
        backtrack(end - 1, remain, cur_result)

    backtrack(len(coins) - 1, amount, [])
    return res

测试:

print(change([1, 2, 5, 8], 7))
print(change([2], 10))

输出:

[[5, 2], [5, 1, 1], [2, 2, 2, 1], [2, 2, 1, 1, 1], [2, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]]
[[2, 2, 2, 2, 2]]

希望对您有所帮助,如果您还有其他问题,请发表评论。 :)

【讨论】:

  • 感谢您的帮助,它几乎是正确的。当我使用这个测试用例时。 print(change([51, 1], 10)) 它返回 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]。
  • 如果你想要所有的结果,我可以写一个不同的版本,但是动态编程只能得到最好的结果@Don
  • 我正在尝试解决 LeetCode 上的问题,这里是链接 leetcode.com/problems/coin-change,但我想让它在列表中返回。我真的很感谢你的帮助。你很坚强。
  • 我认为你的代码是这个问题的解决方案,如果你想得到具体的结果,你应该在这里编辑你的问题,因为你的描述是get all the coins that are the sum of target amount,它是模棱两可的:)@Don
  • 我已更新版本以输出所有结果,以备不时之需。 @唐
【解决方案2】:

我相信这就是您正在寻找的答案,请提出您的问题,以便我们更好地了解需要做什么:)

def change(coins, amount):
    ret = []    # Here we keep all possible solves
    solves = [] # Here we keep all unique solves, to avoid duplicates (Eg.: [5, 2] and [2, 5] are both a solution to 7)

    for c1 in coins:
        for c2 in coins:
            if c1 + c2 == amount: # Check if the solve is a match
                solve = [c1, c2] 
                if not set(solve) in solves: # Check if the solve is not a duplicate
                    ret.append(solve)
                    solves.append(set(solve))

    return ret # Return a list of solves

【讨论】:

  • 如果您用您如何理解 OP 的信息扩展您的答案,可能会有所帮助
【解决方案3】:

如果要获取与目标金额对应的所有组合,可以使用以下生成器:

def change(coins, amount):
    for i, coin in enumerate(coins):
        if coin == amount:
            yield (coin,)
        elif coin < amount:
            yield from ((coin,) + x for x in change(coins[i:], amount - coin))

print(list(change([2], 10)))  # [(2, 2, 2, 2, 2)]
print(list(change([1, 2, 5, 8], 7)))  # [(1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 2), (1, 1, 1, 2, 2), (1, 1, 5), (1, 2, 2, 2), (2, 5)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2018-02-25
    相关资源
    最近更新 更多