【问题标题】:An algorithm to solve the postage stamp problem recursively一种递归求解邮票问题的算法
【发布时间】:2019-04-03 02:56:19
【问题描述】:

这是一个被称为“邮票问题”的数学问题。您需要在信封上放置一定数量的邮资(amount)。 信封上只有 n 个邮票的空间(但没有更多)。

有一个可用面额的邮票列表(面额)。您可以根据需要使用尽可能多的每种面额。目标是使用 面额 和有限的 n 个邮票获得所需的数量

例如,金额 =12,n =3,面额 => 5+5+2。但是你根本无法使 amount =17。

我怎样才能递归解决这个问题?

我已经能够确定基本情况。例如,当你超过价值限制,或者你没有地方可以盖章时,这些​​都是失败的尝试,当你达到目标时,这是一个应该返回 true 的积极尝试。 递归的诀窍是找到所有可能组合的总和。

Java 中的算法或代码的轻微提示将不胜感激。

【问题讨论】:

  • 你可以尝试一下吗?
  • 使用永久邮票。
  • @TerryDorsey 我能够确定基本情况。例如,当你超过价值限制,或者你没有地方可以盖章时,这些​​都是失败的尝试,当你达到目标时,这是一个应该返回 true 的积极尝试。递归的诀窍是找到所有可能组合的总和
  • 如果你第一次尝试拿一个 9-stamp 剩下的可以看作是新的简化问题amount=3, n=2
  • 另外,“you could not make amount =17”实际上是错误。两张 9 美分的邮票。您多付了 1 美分,但那只是两张邮票,邮政部门会很乐意接受您的多付。

标签: java algorithm recursion discrete-mathematics


【解决方案1】:

这是一种子集和问题。

递归函数应该提供:

 stop condition: 
     when sum is zero and left count is zero - success
     when sum is zero and left count is non-zero - fail
     when sum is negative - fail
 traverse possible variants to solve simpler problem at the next recursion level:
     for every stamp value v check - 
       is it possible to make solution using value v and result of recursive call for count n-1
  (note: to avoid duplicate solutions, start traversal from the same stamp index, omitting lower indexes)

【讨论】:

    【解决方案2】:

    如果你想要的只是一个蛮力解决方案,那么简单的方法就可以了:

    Solve(amount, denoms[1...m], partial[1...n], pos, sum)
    1. if sum = amount then print partial[1...n], pos - 1
    2. if pos <= n then
    3.    for i = 1 to m do
    4.       partial[pos] = denoms[i]
    5.       Solve(amount, denoms[1...m], partial[1...n], pos + 1, sum + denoms[i])
    6.    partial[pos] = 0
    

    使用它的方法是拨打电话Solve(amount, denoms[1...m], partial[1...n], 1, 0)。这将打印所有解决方案以及遇到的每个解决方案的长度。请注意,这将打印出每个解决方案的所有排列,因此它做了很多不必要的工作;此外,即使超出数量,它也会继续递归。这两个问题都可以通过几行额外的代码来解决 - 例如,仅在当前总和小于或等于金额时才进行递归调用,并跟踪迄今为止使用的最小面额并仅使用面额该大小或更小 - 但这些性能改进不会以渐近有意义的方式改变方法的性能(即,这些不会使算法成为多项式时间)。事实上,这个问题可能很容易被简化为一个 NP 完全问题,因此它可能没有可访问的多项式时间解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-12
      • 1970-01-01
      • 2022-01-05
      • 2012-12-25
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      • 2021-10-14
      相关资源
      最近更新 更多