📌  相关文章
📜  将长度为N的棍子切成K片的方法数量

📅  最后修改于: 2021-04-27 21:22:13             🧑  作者: Mango

给定大小为N的木棒,找到将其切成K块的方法,以使每块的长度都大于0。

例子 :

输入:N = 5 K = 2输出:4 除法棍输入:N = 15 K = 5输出:1001

解决此问题等同于解决数学方程x 1 + x 2 +….. + x K = N
我们可以通过组合数学中的条形和星形方法来解决此问题,由此得出一个事实:该方程的正积分解数为(N – 1) C (K – 1) ,其中N C K为N! /(((N – K)!*(K!))),其中!代表阶乘。

在C++和Java,对于较大的阶乘,可能会发生溢出错误。在这种情况下,我们可以引入较大的质数(例如10 7 + 7)来修改答案。我们可以使用卢卡斯定理计算nCr%p。
但是, Python可以处理较大的值而不会溢出。

C++
// C++ program to calculate the number of ways
// to divide a stick of length n into k pieces
#include 
using namespace std;
  
// function to generate nCk or nChoosek
unsigned long long nCr(unsigned long long n,
                       unsigned long long r)
{
    if (n < r)
        return 0;
  
    // Reduces to the form n! / n!
    if (r == 0)
        return 1;
  
    // nCr has been simplified to this form by
    // expanding numerator and denominator to 
    // the form   n(n - 1)(n - 2)...(n - r + 1)
    //             -----------------------------
    //                         (r!)
    // in the above equation, (n - r)! is cancelled 
    // out in the numerator and denominator
  
    unsigned long long numerator = 1;
    for (int i = n; i > n - r; i--)
        numerator = (numerator * i);
  
    unsigned long long denominator = 1;
    for (int i = 1; i < r + 1; i++)
        denominator = (denominator * i);
  
    return (numerator / denominator);
}
  
// Returns number of ways to cut 
// a rod of length N into K pieces.
unsigned long long countWays(unsigned long long N,
                             unsigned long long K)
{
    return nCr(N - 1, K - 1);
}
  
// Driver code
int main()
{
    unsigned long long N = 5;
    unsigned long long K = 2;
    cout << countWays(N, K);
    return 0;
}


Java
// Java program to find the number of ways in which
// a stick of length n can be divided into K pieces
import java.io.*;
import java.util.*;
  
class GFG
{
    // function to generate nCk or nChoosek
    public static int nCr(int n, int r)
    {
        if (n < r)
            return 0;
  
        // Reduces to the form n! / n!
        if (r == 0)
            return 1;
  
        // nCr has been simplified to this form by
        // expanding numerator and denominator to 
        // the form  n(n - 1)(n - 2)...(n - r + 1)
        //             -----------------------------
        //                          (r!)
        // in the above equation, (n-r)! is cancelled 
        // out in the numerator and denominator
  
        int numerator = 1;
        for (int i = n ; i > n - r ; i--)
            numerator = (numerator * i);
  
        int denominator = 1;
        for (int i = 1 ; i < r + 1 ; i++)
            denominator = (denominator * i);
  
        return (numerator / denominator);
    }
  
    // Returns number of ways to cut 
    // a rod of length N into K peices
    public static int countWays(int N, int K)
    {
        return nCr(N - 1, K - 1);
    }
  
    public static void main(String[] args)
    {
        int N = 5;
        int K = 2;
        System.out.println(countWays(N, K));
    }
}


Python3
# Python program to find the number 
# of ways  in which a stick of length 
# n can be divided into K pieces
  
# function to generate nCk or nChoosek
def nCr(n, r):
  
    if (n < r):
        return 0
  
    # reduces to the form n! / n!
    if (r == 0):
        return 1
  
    # nCr has been simplified to this form by
    # expanding numerator and denominator to 
    # the form     n(n - 1)(n - 2)...(n - r + 1)
    #             -----------------------------
    #                         (r!)
    # in the above equation, (n-r)! is cancelled 
    # out in the numerator and denominator
  
    numerator = 1
    for i in range(n, n - r, -1):
        numerator = numerator * i
  
    denominator = 1
    for i in range(1, r + 1):
        denominator = denominator * i
  
    return (numerator // denominator)
  
# Returns number of ways to cut 
# a rod of length N into K peices.
def countWays(N, K) :
    return nCr(N - 1, K - 1);
  
# Driver code
N = 5
K = 2
print(countWays(N, K))


C#
// C# program to find the number of 
// ways in which a stick of length n 
// can be divided into K pieces
using System;
  
class GFG
{
    // function to generate nCk or nChoosek
    public static int nCr(int n, int r)
    {
        if (n < r)
            return 0;
  
        // Reduces to the form n! / n!
        if (r == 0)
            return 1;
  
        // nCr has been simplified to this form by
        // expanding numerator and denominator to 
        // the form  n(n - 1)(n - 2)...(n - r + 1)
        //             -----------------------------
        //                          (r!)
        // in the above equation, (n-r)! is cancelled
        // out in the numerator and denominator
  
        int numerator = 1;
        for (int i = n; i > n - r; i--)
            numerator = (numerator * i);
  
        int denominator = 1;
        for (int i = 1; i < r + 1; i++)
            denominator = (denominator * i);
  
        return (numerator / denominator);
    }
  
    // Returns number of ways to cut 
    // a rod of length N into K pieces
    public static int countWays(int N, int K)
    {
        return nCr(N - 1, K - 1);
    }
  
    public static void Main()
    {
        int N = 5;
        int K = 2;
        Console.Write(countWays(N, K));
      
    }
}
  
// This code is contributed by nitin mittal.


PHP
 $n - $r; $i--)
        $numerator = ($numerator * $i);
  
    $denominator = 1;
    for ($i = 1; $i < $r + 1; $i++)
        $denominator = ($denominator * $i);
  
    return (floor($numerator / $denominator));
}
  
// Returns number of ways to cut 
// a rod of length N into K peices.
function countWays($N, $K)
{
    return nCr($N - 1, $K - 1);
}
  
// Driver code
$N = 5;
$K = 2;
echo countWays($N, $K);
return 0;
  
// This code is contributed by nitin mittal.
?>


输出 :

4 

锻炼 :
扩展上述问题,允许使用0个长度的片段。提示:通过将每个x i都写为y i – 1可以类似地找到解的数量,我们得到一个等式y 1 + y 2 +….. + y K = N + K。该方程的解数为(N + K – 1) C (K – 1)