【问题标题】:Find if a number is a possible sum of two or more numbers in a given set - python查找一个数字是否是给定集合中两个或多个数字的可能总和 - python
【发布时间】:2013-04-21 19:21:20
【问题描述】:

办公用品商店以 5、8 或 24 支的包装出售您最喜欢的钢笔类型。因此,例如,可以正好买 13 支钢笔(一包 5 支,第二包 8 支),但不可能正好买 11 支钢笔,因为没有 5 和 8 的非负整数组合和 24 加起来是 11。要确定是否有可能恰好购买 n 支笔,必须找到 a、b 和 c 的非负整数值,使得

5a + 8b + 24c = n

编写一个名为 numPens 的函数,该函数接受一个参数 n,如果可以购买 5、8 和 24 包单位的组合以使笔的总数正好等于 n,则返回 True,否则返回 False .

注意:这是上个月期中考试中提出的问题。我无法解决它,但仍在寻找解决方案。任何帮助都将被接受。 python中的代码或解决它的算法。谢谢

【问题讨论】:

  • 这是背包问题的一个直接变体。
  • 这是模数/除法运算,只需要检查 N 是否大于 24,N % 24 = 余数;如果余数 > 8,N % 8 = 余数;如果余数 > 5,N % 5 = 余数;返回余数 == 0
  • @David:如果我正确理解你的算法,那就错了。考虑 N = 25。您的算法将得出结论,没有解决方案(因为它抓取 24 包,但随后找不到 1 包),而实际上 5+5+5+5+5=25 是一个解决方案.
  • @JeremyRoman 是的,刚刚在 Idle 中测试并发现了这一点,>= 进行比较会起作用。其他边缘也很少(如果 N

标签: python


【解决方案1】:

这听起来很适合dynamic programming

def numPens(n):
  pen_sizes = [5, 8, 24]
  results = [True]
  for i in range(1, n+1):
    results.append(any(i >= size and results[i - size] for size in pen_sizes))
  return results[n]

这里的主要见解是:

  1. 可以实现 0 支笔(简单来说:每种尺寸 0 包)。
  2. 如果我们已经知道少于 n 笔的答案,我们就可以算出是否可以得到 n 笔。

例如,假设我们想知道是否可以得到 10 支钢笔,假设我们已经知道 0 到 9 的答案。那么,我们至少需要一包才能做到这一点。那么有3种情况需要考虑:

  1. 一包 5 支以上,但如果可能的话,我们会得到 5 支钢笔。
  2. 一包 8 支以上,但如果可能的话,我们会得到 2 支笔。
  3. 一包 24 支以上,但如果可能的话,我们会得到 -14 支钢笔。

最后一个是无意义的,因此当(且仅当)有可能获得 5 支或 2 支时,获得 10 支笔是可能的。因为我们假设我们已经知道 0 到 9 的答案,所以我们可以解决这个问题(事实证明,5 支笔是可能的,作为一包 5 支,因此我们得出结论,10 支也是如此)。

因此,为了让自己处于总是有较小 n 值的答案的情况,我们从 0 的明显答案开始。然后我们计算 1 的答案(因为我们已经有了 0 的答案, 我们可以完成这个)。然后我们计算 2 的答案(因为我们已经有了 0 和 1,我们可以这样做),依此类推,直到我们得到我们想要的 n 的答案。

这段代码封装了对先前结果的实际计算:如果有任何包装尺寸size,它会产生True,对于购买该尺寸的包装是有意义的(不会得到负数) i - size),我们之前有 找到了购买i - size钢笔的方法。

any(i >= size and results[i - size] for size in pen_sizes)

其余代码只是让我们将该结果存储在results 列表中以供将来使用,并最终返回最终结果。

【讨论】:

  • 它像魔术一样工作,但可悲的是我不明白发生了什么,我的意思是算法。感谢您的解决方案
猜你喜欢
  • 2021-07-05
  • 1970-01-01
  • 2011-07-06
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多