我正在尝试使用动态编程来解决问题,问题如下:
给予无限量的硬币(便士,镍,一角钱,二角钱,四分之一) 值(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
答案 0 :(得分:1)
你做错了。列表示您必须返回的总变化,行单元格表示使用的某些硬币(便士,镍币,硬币,二角硬币,四分之一)的数量。
该算法的重点是返回最小数量的硬币。例如,如果更改为25,则应返回单个季度,而不是25个便士。您可以看到我在下表中使用了四分之一的25美分列。
在15更改列中的示例中,您使用的是4 x 5cents,这是次优的,因为您可以使用一个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行来计算您用作更改的硬币总数。你的目标是获得最低分。每列可能在此行中编号。
答案 1 :(得分:0)
仍然使用动态编程,我会将问题建模为构建一个图表,其中节点是金额(节点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}
。