【问题标题】:Dynamic Programming: the smallest number of coins to make change for 65 cents动态规划:65美分找零的最少硬币数量
【发布时间】:2014-10-29 21:41:57
【问题描述】:

我正在尝试使用动态编程解决问题,问题如下:

给定无限供应的硬币(一分钱、五分钱、一角硬币、一角硬币、四分之一硬币) 值 (1, 5, 10, 20, 25),请找出最少的硬币数量来找零 65 美分。 使用了哪些硬币(每种硬币有多少)?使用 动态规划算法以及如何获得使用的硬币。

请注意,我不希望任何人为我说明整个表格,但我对如何为这个问题填写表格感到有点困惑。

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

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

5

10

20

25

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

    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

【问题讨论】:

  • 这个问题对你有帮助吗? stackoverflow.com/questions/8031816/…
  • 您可能需要重新考虑您接受的解决方案。你选择的答案是错误的。
  • 我删除了错误的评论,但我的回答没有任何错误,仍然回答了问题。

标签: algorithm dynamic-programming


【解决方案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 行来计算您用作零钱的硬币总数。你的目标是获得最小。每一列在这一行中可能存在的数字。

【讨论】:

  • 谢谢你,我明白了。我将编辑我的答案,以确保我有正确的答案。但是对于 65,我得到 2twentyfive、10 和 1five
  • 如果目标数量是67呢?每个金额都需要有列,而不仅仅是 5 的倍数。此外,两个 25、一个 10、1 个 5 的答案不是最优的。一个 25 岁,两个 20 岁是最佳的。
  • @Timothy Shields,您对 65 的最佳硬币数量是正确的,但我没有在我的回答中提到 65 的解决方案,我不明白您为什么认为这是错误的。我刚刚为他指明了填满表格的正确方向。
  • 关于列,它们是任意的,它们是由用户提供的。您可以设置任何列数量,并且填充它的逻辑仍然有效。它仍然适用于 67 = 1x25 + 2x20 + 2x1
【解决方案2】:

我仍然使用动态规划,而是将问题建模为构建一个图,其中节点是金额(节点 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}

【讨论】:

  • 虽然您的回答可能有用,但并不能回答他的问题。他并没有问如何最有效地解决问题或解决问题的替代方法,但他特别要求解释动态规划问题并请求帮助以填补表格:)
猜你喜欢
  • 1970-01-01
  • 2015-05-08
  • 2020-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-11-05
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多