【问题标题】:Different way int n can be split in groups of 1 or 2不同的方式 int n 可以分成 1 或 2 组
【发布时间】:2018-09-30 03:31:55
【问题描述】:

这是向我提出的作业问题:

一个病人有 n 颗药丸要吃。每天,他可以服用任何一种 药丸或两丸,直到所有药丸都消失。让 T(n) 表示数字 患者可以服用所有 n 颗药丸的不同方式。给出一个封闭的表格 对于 T(n)。 (请注意 - 例如 - 两个序列 (1, 2, 2) 和 (2, 1, 2) 被认为是服用 5 颗药丸的两种不同方式。)

我尝试对 n = 1 到 8 的集合进行处理,看看是否能找到这样的模式:

n=1 {1} n=2 {{1,1},{2}} n=3 {{1,1,1},{1,2},{2,1}} n=4 {{1,1,1,1},{1,1,2},{1,2,1},{2,1,1},{2,2}} ...

但是没办法。 n=1-8 的组合是 1,2,3,5,8,12,18,25

有人有想法吗?

【问题讨论】:

    标签: algorithm time time-complexity combinatorics


    【解决方案1】:

    您的示例在 8 之后显示错误值(应该是 13...)。

    考虑下一种方法:在最后一天,患者可以吃一粒或两粒(n = (n-1) + 1n = (n-2) + 2)。所以组成 T(n) 值的方法数是

    T(n) = T(n-1) + T(n-2)
    

    对 T(n-1) 和 T(n-2) 重复相同的过程,您将在 T(0) 或 T(1) 处完成 - 这些值显然等于 1。

    因此构建循环序列并解决任何 n 的循环。

    请注意,您可以从末尾展开循环(递归方法)并从 0/1 - 迭代方法开始。

    当您找到正确的值时,您可能会发现它们形成了著名的序列并阅读了更多相关信息。

    【讨论】:

    • 是的,我已经看到了斐波那契模式,但是让我失望的是,当我继续构建可能的集合时,n = 6 的可能性集合给了我 12,而不是 13。就像这样: {{1,1,1,1,1,1}, {1,1,1,1,2}, {1,1,1,2,1}, {1,1,2,1,1} , {1,2,1,1,1}, {2,1,1,1,1}, {2,2,1,1}, {2,1,2,1}, {1,2, 2,1}, {1,2,1,2}, {1,1,2,2}, {2,2,2}} 如您所见,12 个组合不是 13 个。对于 n=7,同样如此, 8,...这就是为什么我驳回了我已经考虑过的 T(n) = T(n-1) + T(n-2) 。除非我做错了什么。
    • 错过{2,1,1,2}
    • 是的,你是对的。我一直错过所有系列的中间序列。我也做了几次,因为我最初看到了斐波那契模式。哇,现在我觉得自己很傻哈哈。感谢您的帮助。
    【解决方案2】:

    这是解决此问题的另一种方法,当您将其视为排列和组合问题时,它会变得非常有趣。

    我们一起来

    n = 6 as a example, 
    

    我们说

    d = number of days patient takes to take all n pills
    
    maximum number of days patient can take those pills are 6. (1 for each day).
    minimum would be 3. (2 for every day).
    
    when d = 6 => {1,1,1,1,1,1} 
    so when d = 3 => {2,2,2}
    
    when d = 4 => {1,1,2,2}. patient can take this pills in any order in those 4 days. 
    so number of combinations are = 4!/2!2! = 4C2.
    
    when d = 5 => {1,1,1,1,2}.
    number of combinations = 5!/4!1! = 5C1.
    
    when d = 6 => {1,1,1,1,1,1}. 
    number of combinations = 6!/6!0! = 6C0.
    

    让,回到最少天数,

    when d = 3 => {2,2,2} => 3!/0!3! => 3C3. 
    

    现在你可以很容易地在阶乘中看到一个模式,

     when d = d => d!/(numberOf1s)!*(numberOf2s)!.
    

    这么多不同的方式 患者可以服用全部 6 颗药丸

    T(6) = 3C3 + 4C2 + 5C1 + 6C0.
    T(6) = 1 + 6 + 5 + 1 
    T(6) = 13; 
    

    根据上面的模式,这里是算法,

    d_M - maximum number of days;
    

    d_m - minimum number of days;
    

    T(n) -  number of different ways the patient can take all n pills
    

    这就是你可以用简单的javascript做到这一点的方法,

    function numberOfDiffWays(n){
    
      var dmin = Math.ceil(n/2);
      var dmax = n;
      var sum = 0;
    
      for(var d= dmin; d<=dmax; d++){
        sum = sum + nCr(d,(2*d-dmax));
      }
      return sum;
    }
    
    function nCr(n,r) { 
        return fact(n) / (fact(r) * fact(n - r)); 
    } 
    
    function fact(n) { 
      return n==0 ? 1: n*fact(n-1);
    } 
    
    console.log("n=1: " + numberOfDiffWays(1)); // 1
    console.log("n=2: " + numberOfDiffWays(2)); // 2
    console.log("n=3: " + numberOfDiffWays(3)); // 3
    console.log("n=4: " + numberOfDiffWays(4)); // 5
    console.log("n=5: " + numberOfDiffWays(5)); // 8
    console.log("n=6: " + numberOfDiffWays(6)); // 13
    console.log("n=7: " + numberOfDiffWays(7)); // 21
    

    希望对你有帮助。

    【讨论】:

    • 这是一种非常低效的计算斐波那契数列的方法,尽管身份很有趣(并且众所周知)。
    • 是的。我同意。但这是看待问题的一种有趣方式。如果这涉及超过 2 个药丸或更改问题的条件,它可能无法通过斐波那契解决。
    • 如果问题的条件在某些未指定的情况下发生变化,您的解决方案也可能不起作用。它变成了一个完全不同的问题。但是,如果改变只是为了改变可能的增量数量,那么类似斐波那契的递归仍然适用,并且所有此类递归都可以在 O(log N) KxK 矩阵乘法中求解(其中矩阵大小 K 是可能的最大增量)或更直接的方式与 O(KN) 加法,只需迭代递归公式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多