Algorithm 动态规划:65美分的最小硬币数量

Algorithm 动态规划:65美分的最小硬币数量,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我正在尝试使用动态规划解决一个问题,问题如下: 不受限制地供应硬币(便士、镍币、一角硬币、双角硬币、四分之一硬币) 数值(1、5、10、20、25),请找到最小数量的硬币,兑换65美分。 使用了哪些硬币(以及每种硬币的数量)?说明使用 动态规划算法以及如何获得使用的硬币 注:我不希望有人为我说明整个表格,但我对如何填写这个问题的表格有点困惑 我知道我的桌子看起来有点像这样: 5 10 15 20 25 30 35 40 45 50 55 60 65 1 5

我正在尝试使用动态规划解决一个问题,问题如下:

不受限制地供应硬币(便士、镍币、一角硬币、双角硬币、四分之一硬币) 数值(1、5、10、20、25),请找到最小数量的硬币,兑换65美分。 使用了哪些硬币(以及每种硬币的数量)?说明使用 动态规划算法以及如何获得使用的硬币

注:我不希望有人为我说明整个表格,但我对如何填写这个问题的表格有点困惑

我知道我的桌子看起来有点像这样:

    5   10  15  20  25  30  35  40  45  50  55  60  65
1

5

10

20

25
    5   10   15  20  25  30  35  40  45  50  55  60  65
1

5   1    2   4   5    5   6  7   8    9  10  11  12  13

10  0    1   

20

25
(我省略了1,因为我知道这不是最好的解决方案) 我最初的想法是表格的填写有点像这样:

    5   10  15  20  25  30  35  40  45  50  55  60  65
1

5

10

20

25
    5   10   15  20  25  30  35  40  45  50  55  60  65
1

5   1    2   4   5    5   6  7   8    9  10  11  12  13

10  0    1   

20

25
当我不得不走得更远时,我会被困在这里。我不认为我完全理解动态规划是如何解决这个问题的。我一直在读我的书,在网上阅读,但我仍然有点困惑

编辑:

多亏了其中一个答案,我才得出了解决方案:

    5     10    15    20    25    30    35    40    45    50    55    60    65
1   

5   1           1                  1                             1           

10         1    1                       1                              1     

20                    1                       2     1                        2

25                          1      1    1           1      2     2     2     1

你做错了。列表示您必须返回的总更改,行单元格表示使用的特定硬币(便士、镍、一角硬币、双角硬币、四分之一硬币)的数量

该算法的全部要点是返回最小数量的硬币。例如,如果零钱是25美分,您应该返回一个季度,而不是25便士。你可以看到,我在下表的25美分栏中使用了四分之一

在“15个零钱”列中的示例中,您使用的是4 x 5个硬币,这是次优的,因为您可以使用一枚10美分的硬币和一枚5美分的硬币来返回15个零钱。在20美分一栏中,您使用的是5 x 5美分的零钱,这是不正确的,也是不理想的,因为您可以使用一枚20美分的硬币来返还20美分

下面是前5列的表格。您可以填写以下内容:

    5   10   15  20  25  30  35  40  45  50  55  60  65
1

5   1        1     

10      1    1  

20               1

25                   1
--------------------------------------------------------
T   1   1    2   1   1

我在底部添加了一个T行,以计算您用作零钱的硬币总数。您的目标是为每一列在这一行中提供可能的最小值。

仍然使用动态规划,我将把问题建模为构造一个图,其中节点是货币数量(节点N是N美分),其中有5种类型的有向边,{1,5,10,20,25},对应于硬币类型

保持尚未找到最佳解决方案的节点的运行边界。每次迭代,边界上的最小节点必须是最优的,因此可以删除它,在边界上添加多达5个新节点

下面是算法的Python:

def change(coins, target):
    nodes = {0: (0, None)}
    frontier = set([0])
    while True:
        n = min(frontier)
        frontier.remove(n)
        if n == target:
            break
        elif n > target:
            return None # Infeasible!
        count = nodes[n][0]
        for coin in coins:
            m = n + coin
            frontier.add(m)
            if not m in nodes or nodes[m][0] > count + 1:
                nodes[m] = (count + 1, n)
    m = target
    sol = {}
    while True:
        n = nodes[m][1]
        if n is None:
            break
        coin = m - n
        sol[coin] = sol.get(coin, 0) + 1
        m = n
    return sol

print change([1, 5, 10, 20, 25], 65)

输出是
{25:1,20:2}

这个问题对您有帮助吗?您可能需要重新考虑您接受的解决方案。你选择的答案是错误的。我删除了错误的评论,但我的答案没有任何错误,仍然回答了问题。啊,谢谢你,我现在明白了。我将编辑我的答案,只是为了确保我有正确的答案。但是对于65,我得到了2个25,1个15和1个5如果目标金额是67呢?每一笔钱都需要列,而不仅仅是5的倍数。此外,答案2 25,1 10,1 5不是最优的。一个25,两个20是最佳的。@Timothy Shields,关于65的最佳硬币数量,你是正确的,但我的答案中没有提到65的解决方案,我不明白你为什么认为这是错误的。我刚刚为他指出了正确的方向来填充表格。关于列,它们是任意的,并且是由用户提供的。您可以设置任何列的数量,填充该列的逻辑仍然有效。它仍然适用于67=1x25+2x20+2x1。虽然你的答案可能有用,但它不能回答他的问题。他没有问如何最有效地解决问题,也没有问解决问题的替代方法,但他特别要求解释动态规划问题,并要求帮助填写表格:)