查找一个数字是否是给定集合中两个或更多个数字的可能总和--python

时间:2013-04-21 19:21:21

标签: python

办公用品商店以5,8或24支包装出售您喜爱的笔类型。因此,例如,可以准确地购买13支笔(一个包装为5个,第二个包装为8个),但是不可能只购买11支笔,因为没有5个,8个非负整数组合。为了确定是否可以精确地购买n笔,必须找到a,b和c的非负整数值,以便

5a + 8b + 24c = n

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

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

1 个答案:

答案 0 :(得分:3)

这听起来像是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笔的答案,我们可以弄清楚是否可以获得笔。
  3. 例如,假设我们想知道我们是否可以获得10笔,假设我们已经知道0到9的答案。那么,我们至少需要一个包才能这样做。然后有3个案例要考虑:

    1. 一包5 +但是我们得到5笔,如果它可以得到5笔。
    2. 一包8 +但是我们得到2笔,如果它可以得到2笔。
    3. 一包24 +但我们得到-14笔,如果它可以得到-14笔。
    4. 最后一个是荒谬的,所以如果(并且只有)可以获得5笔或获得2笔,则可以获得10支笔。由于我们已经假设我们已经知道了0到9的答案,我们可以解决问题(事实证明,5个笔是可能的,因为我们得出结论10也是如此)。

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

      这段代码封装了以前结果的实际结果计算结果:如果有任何包装尺寸True,它会产生size,因此购买这种尺寸的包装是有意义的(没有获得i - size)的负数,而我们之前已经这样做了 找到了购买i - size笔的方法。

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

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