【问题标题】:What is the difference between approaches to "coin change" and "Number of of ways of climbing staircase"“硬币兑换”和“爬楼梯的方式数”有什么区别
【发布时间】:2014-01-19 09:54:00
【问题描述】:

我遇到了两个动态编程问题。问题之一是

考虑到我一次可以跳 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

当我正要思考的时候,我理解了上面的方法,我遇到了硬币找零的问题

给定无限数量的 25 美分硬币、10 美分硬币(角钱)、5 美分硬币(镍)和 1 美分硬币,表示 n 美分的方式是多少

事实证明,这个问题的解决方案与上面的解决方案不同,而且有点复杂。那是 , C(n) = C(n-1) + C(n-5) + C(n-10) + C(n-25) 不正确。我仍在尝试了解解决此问题的方法。但我的问题是硬币找零问题与更简单的攀爬步骤问题有何不同?

【问题讨论】:

  • 因为更改时订单不计算在内。

标签: recursion dynamic-programming


【解决方案1】:

Scott 的解决方案是绝对正确的,他提到了这两个问题不同的症结所在。这里对这两个问题进行了更多的说明,以帮助直观地理解差异。

对于涉及递归的动态编程问题,诀窍是正确处理子问题。一旦子问题是正确的,就只需要在此基础上进行构建即可。

楼梯问题处理序列,因此子问题更容易直观地看到。对于硬币找零问题,我们正在处理 counts,因此子问题是围绕是否使用特定面额。我们使用面额计算解决方案的一部分,而不使用它来计算另一部分。这是一个更难看到的洞察力,但一旦看到,您就可以递归地计算其余部分。

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

楼梯序列

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

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

硬币变化

推出一种新的小硬币面额。假设新推出了一种面额为“m”的硬币。 我们现在如何计算 C[n],知道 C[N,除了 m] 之外的所有硬币?

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

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

希望对您有所帮助。

【讨论】:

  • 在楼梯问题中我们计算排列而在硬币找零问题中我们计算组合是否正确?
  • @Saurabh 是的,这是一个很好的类比。然而,由于这两个问题(硬币变化和计步)都涉及递归,所以发生的不仅仅是排列和组合。也就是说,你的想法是“定向”正确的。
【解决方案2】:

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

【讨论】:

  • 你能帮我理解如何反驳这样的说法吗...如果我达到 n-1 的值,我可以通过一个 1 美分硬币达到 n 或者如果我达到 n-5 ,我可以通过一枚 5 美分硬币到达 n ,或者如果我达到 n-10 ,我可以通过一枚 10 美分硬币达到 n 等等......所以我可以写 C(n) = C(n-1) + C(n-5) + C(n-10) + C(n-25)..
  • @quirkystack Um Scott 刚刚解释过。如果找 6 美分,一便士加一美分等于一美分加一便士吗?
猜你喜欢
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 2016-06-23
  • 2020-11-09
  • 1970-01-01
相关资源
最近更新 更多