在动态编程硬件示例中使用无穷大 - 为什么这不会失败?

时间:2015-04-22 09:58:18

标签: python dynamic-programming

一直试图了解如何在此页面上使用动态编程

https://www.topcoder.com/community/data-science/data-science-tutorials/dynamic-programming-from-novice-to-advanced/

给出N个硬币的列表,它们的值(V1,V2,...,VN)和总和S.找到其总和为S的最小硬币数量(我们可以使用一种类型的硬币)正如我们所希望的那样),或者报告说不可能选择硬币,使它们总和为S。

给出值为1,3和5的硬币。 并且总和S设置为11。

Set Min[i] equal to Infinity for all of i
Min[0]=0

For i = 1 to S
For j = 0 to N - 1
   If (Vj<=i AND Min[i-Vj]+1<Min[i])
Then Min[i]=Min[i-Vj]+1

Output Min[S]

我很困惑为什么我们为所有人设置无限。

当总和为1时,更令人困惑的是

If (Vj<=i AND Min[i-Vj]+1<Min[i]) 

Min [1]不会被定义吗?代码不会在这里失败吗?他们为什么要加+1?

还是会继续,因为它是无限的?他们为什么在这里使用无限?什么是N-1他们从哪里得到它?

总的来说,我发现他们的解释非常难以理解。

1 个答案:

答案 0 :(得分:2)

希望直接翻译:

def dp_coin(S, coins):
    # set all values to infinity in range S/sum needed
    mn = [float("inf") for j in range(S+1)]
    # takes 0 coins to sum 0
    mn[0] = 0
    # start at second index 1
    for i in range(1, S+1):
        for j in range(len(coins)):
            if coins[j] <= i and mn[i-coins[j]]+1 < mn[i]:
                mn[i] = mn[i-coins[j]] + 1
    return mn[-1]

print(dp_coin(11, [1, 3, 5]))
3

如果你打印mn,你会看到:

[0, 1, 2, 1, 2, 1, 2, 3, 2, 3, 2, 3]

与表格相同:

Sum Min. nr. of coins   Coin value added to a smaller sum to
obtain this sum (it is displayed in brackets)
0   0   -
1   1   1 (0)
2   2   1 (1)
3   1   3 (0)
4   2   1 (3)
5   1   5 (0)
6   2   3 (3)
7   3   1 (6)
8   2   3 (5)
9   3   1 (8)
10  2   5 (5)
11  3   1 (10)

S是指所需的总金额,coins[j]相当于VjN指的是硬币。

可以删除内部循环并简单地遍历硬币:

def dp_coin(S, coins):
    mn = [float("inf") for j in range(S+1)]
    mn[0] = 0
    for i in range(1, S+1):
        for j in coins:
            if j <= i and mn[i-j]+1 < mn[i]:
                mn[i] = mn[i-j] + 1
    return mn[-1]