“硬币改变”方法和“爬楼梯方式数量”之间的区别是什么?

时间:2014-01-02 00:19:48

标签: recursion dynamic-programming

我遇到过两个动态编程问题。其中一个问题是

如果我可以一次跳1步,2步或3步,可以通过n个步骤爬楼梯的数量是多少。

解决此问题的动态编程方法如下:

If C(n) is number of ways of climbing the staircase, then 
C(n) = C(n-1) + C(n-2) + C(n-3) . 
This is because , if we reach n-1 stairs, we can hop to n by 1 step hop or
                  if we reach n-2 stairs, we can hop to n by 2 step hop or
                  if we reach n-3 stairs, we can hop to n by 3 step hop

正如我想的那样,我理解了上述方法,我遇到了硬币变化问题

代表n美分的方式数量是多少,给予无限数量的25美分硬币,10美分硬币(硬币),5美分硬币(镍币)和1美分硬币

事实证明,这个问题的解决方案与上面的问题不同,并且有点复杂。那是 , C(n)= C(n-1)+ C(n-5)+ C(n-10)+ C(n-25)不成立。我仍然试图理解解决这个问题的方法。但我的问题是硬币变化问题与更简单的攀爬步骤问题有何不同?

2 个答案:

答案 0 :(得分:3)

在步骤问题中,顺序很重要:(1,2)与(2,1)不同。由于硬币问题,每种硬币的使用数量都很重要。

答案 1 :(得分:3)

斯科特的解决方案是绝对正确的,他提到了两个问题之间差异的症结所在。这两个问题的颜色多一点,以帮助直观地理解差异。

对于涉及递归的动态编程问题,诀窍是让子问题正确。一旦子问题是正确的,这只是建立在其上的问题。

Staircase问题处理序列,因此子问题更容易直观地看到。对于硬币变化问题,我们正在处理计数,因此子问题是否使用特定面额。我们使用面额计算解决方案的一部分,而不使用面额计算另一部分解决方案。这是一个稍微难以理解的洞察力,但是一旦你看到了,你就可以递归计算其余部分。

所以这是考虑这两个问题的一种方法:

楼梯序列

引入一个新步骤。第n步已添加。我们如何计算S [N]?

S[N] = S[N-1] + S[N-2] + S[N-3]

硬币改变

介绍一种新的小硬币面额。让我们说新引入了一个面额'm'的硬币。 我们如何现在计算C [n],知道C [N,所有硬币除了m]?

所有到达N 而没有硬币的方法仍然有效。但是每个新的硬币面额“m”从根本上改变了到达N的方式。因此,为了计算C [N使用m],我们必须递归地计算C [Nm,使用新的硬币m]和C [N-2m使用m] ]...等等。

C[N, with m] = C[N, without m] + C[N-m, with m]

希望有所帮助。