动态编程 - 硬币

时间:2014-05-20 15:24:40

标签: algorithm dynamic-programming

考虑下面的一段伪代码,其中d是面额值数组,k是面额数,n是更改的数量制成。

Change(d; k; n)
1 C[0]  <- 0
2 for p <-  1 to n
3     min  <- INFINITE
4     for i  <- 1 to k
5         if d[i] <= p then
6           if 1 + C[p - d[i]] < min then
7               min  <- 1 + C[p - d[i]]
8               coin  <- i
9     C[p] <-  min
10    S[p] <-  coin
11 return C and S

我已经阅读了很多关于这个具体问题的信息,但我仍然不明白为什么: 1 + C[p-d[i]] - &gt;我真的没有得到这个部分,你为什么要使用它,有人可以向我解释一下这个部分!

1 个答案:

答案 0 :(得分:4)

为了回答你的问题,你需要了解每个变量代表什么,以及算法的高级别。

算法到达解决方案的过程会尝试计算从1n的所有金额进行更改所需的硬币数量。这就是外循环的目的:它迭代当前的&#34;目标&#34;从1n,让循环体提出该目标的答案。

基本上,算法是这样的:

  • 我知道如果金额为零,我需要零硬币才能做出改变
  • 查看1
  • 需要更改的硬币数量
  • 知道我需要为1更改多少个硬币,查看我需要为2更改多少硬币
  • 知道我需要为12进行更改需要多少硬币,查看我需要为3进行更改的硬币数量
  • 知道我需要为14进行更改需要多少硬币,查看我需要为4进行更改的硬币数量
  • ...
  • 知道我需要为1n-1进行更改需要多少硬币,查看我需要为n进行更改的硬币数量

p的值代表当前目标 - 即我们尝试进行更改的金额。数组C代表我们迄今为止从1p-1的所有金额找到的解决方案。

对于每个金额,算法会尝试使用每个面额d[i]中的硬币来找到解决方案。

现在您已准备好了解1 + C[p-d[i]]的含义:我们正在尝试对p进行更改,因此C[p-d[i]]是提出更改所需的最小硬币数量为p-d[i]。因此,该公式表明&#34;如果我知道需要x个硬币来更改p-d[i],并且我有一个面值为d[i]的硬币,那么我可以达到p添加一个d[i]硬币(因此,表达式的1 + ...部分)。