【问题标题】:Find the no. of ways of getting a sum n with all positive integers less than n找到号码。获得所有小于 n 的正整数的和 n 的方法
【发布时间】:2012-01-01 20:49:02
【问题描述】:

对于一个给定的数字 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  

这个问题可以有一个通用的模式/解决方案吗?

【问题讨论】:

    标签: algorithm math series


    【解决方案1】:

    这个问题被称为Partition Problem,详情请参阅来自wiki的参考链接:

    获取分区函数句柄的一种方法涉及 中间函数 p(k, n),表示 仅使用至少与 k 一样大的自然数对 n 进行分区。为了 任何给定的 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 来输出结果。 IE。直到最后一步的所有P 值都应该按照wiki 的建议进行计算,但是在最后输出结果之前,您应该将其减去1

    【讨论】:

    • @unutbu 是的,但最终结果应该从 1 中减去,实际上所有 P(i,j) 都将按照上面写的方式(在 wiki 中)计算,但对于 P(n)(或P(1,n)) (只是输出值)它应该从 1 中减去。我已经编辑了我的答案,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 2021-07-31
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 2012-01-06
    相关资源
    最近更新 更多