对于给定的数字n,比方说2我们可以使用少于2的数字获得总和2的方式。
1+1 = 2
so, for 2 - just 1 way.
n = 3
1+1+1=3
1+2=3
so,for 3 - it is 2 ways
n = 4
1+1+1+1=4
1+1+2=4
1+3=4
2+2=4
so, for 4 - it is 4 ways
这个问题可以有一个通用的模式/解决方案吗?
答案 0 :(得分:12)
此问题称为Partition Problem,请参阅wiki引用的链接中的详细信息:
获取分区函数句柄的一种方法涉及到 中间函数p(k,n),表示数量 n的分区仅使用至少与k一样大的自然数。对于 任何给定的k值,由p(k,n)计数的分区完全符合 以下类别之一:
smallest addend is k smallest addend is strictly greater than k.
满足第一个条件的分区数是p(k,n -k)。 为了看到这个,想象一下n-k数字的所有分区的列表 到大小至少为k的数字,然后想象每个附加“+ k” 列表中的分区。现在它的清单是什么?作为旁注,一个 可以使用它来定义分区的一种递归关系 中间函数的函数,即
1+ sum{k=1 to floor (1/2)n} p(k,n-k) = p(n),
满足第二个条件的分区数是p(k + 1,n) 因为分区成至少k的不包含部分的部分 确切地说,k必须包含至少k + 1的所有部分。
由于这两个条件是相互排斥的,所以数量 满足任一条件的分区是p(k + 1,n)+ p(k,n -k)。该 因此递归定义的函数是:
p(k, n) = 0 if k > n p(k, n) = 1 if k = n p(k, n) = p(k+1, n) + p(k, n − k) otherwise.
实际上,您可以按memoization计算所有值,以防止额外的递归调用。
编辑:正如他的评论中提到的unutbu,在计算结束时你应该减去1来输出结果。即直到最后一步的所有P
值都应该按照wiki的建议计算,但是在输出结果之前的最后,你应该按1
减去它。