(ProjectEuler)Sum Combinations

时间:2009-01-13 10:26:18

标签: algorithm

来自ProjectEuler.net

问题76:一百个不同的方式可以写成至少两个正整数的总和?

我不知道如何开始这个...正确的方向或帮助的任何点?我不是在寻找如何做到这一点,而是一些提示如何做到这一点。

例如,5可以写成:

4 + 1
3 + 2
3 + 1 + 1
2 + 2 + 1
2 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1

共有6种可能性。

7 个答案:

答案 0 :(得分:38)

Partition Numbers(或分区函数)是这个的关键。

如果你从底部开始向前走,看看是否可以检测到任何模式,这些问题通常会更容易。

  • P(1)= 1 = {1}
  • P(2)= 2 = {[2],[1 + 1]}
  • P(3)= 3 = {[3],[2 + 1],[1 + 1 + 1]}
  • P(4)= 5 = {[4],[3 + 1],[2 + 2],[2 + 1 + 1],[1 + 1 + 1 + 1]}
  • P(5)= 7 ......
  • P(6)= 11 ......
  • P(7)= 15 ......
  • P(8)= 22 ......
  • P(9)= 30 ......

提示:看看你是否可以在P(N)之前的某些结果组合中建立P(N)。

答案 1 :(得分:23)

可以使用斩波算法找到解决方案。

使用例如6.然后我们有:

6
5+1
4+2
3+3

但我们尚未完成。

如果我们取5 + 1,并认为+1部分已完成,因为所有其他结束组合都由4 + 2和3 + 3处理。所以我们需要将相同的技巧应用到5。

4+1+1
3+2+1

我们可以继续。但不是盲目的。因为例如4 + 2产生3 + 1 + 2和2 + 2 + 2。但是我们不想要3 + 1 + 2因为我们会有3 + 2 + 1。所以我们只使用4中最小数大于或等于2的所有产品。

6
5+1
  4+1+1
    3+1+1+1
      2+1+1+1+1
        1+1+1+1+1+1
    2+2+1+1
  3+2+1
4+2
  2+2+2
3+3

下一步是将其放入算法中。

好的,我们需要一个带有两个参数的递归函数。要切碎的数字和最小值:

func CountCombinations(Number, Minimal)
  temp = 1
  if Number<=1 then return 1
  for i = 1 to Floor(Number/2)
    if i>=Minimal then
      temp := temp + CountCombinations(Number-i, i)
  end for
  return temp
end func

检查算法:

C(6,1) = 1 + C(5,1) + C(4,2) + C(3,3) = 11, which is correct.
C(5,1) = 1 + C(4,1) + C(3,2) = 7
C(4,1) = 1 + C(3,1) + C(2,2) = 5
C(3,1) = 1 + C(2,1) = 3
C(2,1) = 1 + C(1,1) = 2
C(1,1) = 1
C(2,2) = 1
C(3,2) = 1
C(4,2) = 1 + C(2,2) = 2
C(3,3) = 1

顺便说一句,组合数为100:

CC(100) = 190569292
CC(100) = 190569291 (if we don't take into account 100 + 0)

答案 2 :(得分:4)

解决这些问题的一个好方法是不要注意'100',而是试着考虑总和 n n + 1 之间的差异是的,通过寻找模式,因为n增加1,2,3 ....

我现在要去,但我有工作要做:)

答案 3 :(得分:2)

与欧拉计划中的大多数问题一样,考虑这些问题的最佳方法就是不要被这个巨大的上限所困扰,并以较小的方式思考问题,并逐步提升。也许,在您识别模式的过程中,或者学习足以让您轻松找到答案。

我认为我可以给你的另一个暗示而不是破坏你的顿悟是“分区”这个词。

一旦你意识到这一点,你马上就会拥有它:)

答案 4 :(得分:2)

一种方法是考虑递归函数:查找从正整数(允许重复)中提取的数字系列的排列,最多可累加100

  • 零为1,即数字1为零解
  • 单位为2,即数字2只有一个解

另一种方法是认为生成函数:从零开始,找到直到目标的排列系列,保持映射/散列或中间值和计数

你可以从1开始迭代,或从100开始递减;你会得到同样的答案。在每个点你可以(对于一个天真的解决方案)生成一系列正整数的所有排列,计数到目标数减去1,并只计算那些加起来的目标数

祝你好运!

答案 5 :(得分:1)

注意:我的数学有点生疏,但希望这会有所帮助......

你对这个问题的分解很顺利。

一般思考:

  • 数字 n 可写为(n-1)+1或(n-2)+2
  • 您将此概括为(n-m)+ m
  • 请记住,以上内容也适用于所有数字(包括m)

所以我的想法是找到第一组(比如5 =(5-1)+1),然后将(5-1)视为一个新的... 5 = 4 +1 ... 5 = ((4-1)+1)+1。耗尽的一次在5 = 3 + 2 ....再次开始变为5 =((3-1)+1)+2 .... = 2 + 1 + 2 ....打破每一个当你一起去。

答案 6 :(得分:1)

induction可以解决许多数学问题。 您知道特定值的答案,如果找到将nn+1链接起来的 ,您就可以找到每个值的答案。

例如在你的情况下,你知道的答案可以用多少种不同的方式写成至少两个正整数的总和?只是1。

nn+1之间的链接是什么意思?好吧,我的意思是你必须找到一个公式,让你知道n的答案,你会找到n+1的答案。然后,递归地调用那个公式,你就会知道答案并且你已经完成了(注意:这只是它的数学部分,在现实生活中你可能会发现这种方法会给你一些太慢而不实用的东西,所以你还没有完成 - 在这种情况下,我认为你将会完成。)

现在,假设你知道n可以用k不同的方式写成至少两个正整数的总和?,其中一个是:< / p>

n = a1 + a2 + a3 + ... am(此总和有m个术语)

您对n+1有什么看法?既然你想要提示我不是在这里写解决方案,而是接下来的内容。当然,你有k个不同的方式,但每个方面都有+1个术语,其中一个是:

n + 1 = a1 + a2 + a3 + ... am + 1(此总和有m + 1项)

然后,当然,你将有其他k种可能性,例如每种金额的最后一个项不相同,但它会增加一个,如:

n + 1 = a1 + a2 + a3 + ...(am + 1)(此总和有m个术语)

因此,至少有2k种方法可以将n+1 写为至少两个正整数的总和。好吧,还有其他的。找出来,如果可以的话:-) 并享受: - ))