📜  二项式系数| DP-9

📅  最后修改于: 2021-04-24 18:34:13             🧑  作者: Mango

以下是二项式系数的常见定义。

问题
编写一个函数,该函数接受两个参数n和k并返回二项式系数C(n,k)的值。例如,你的函数应该返回6对于n = 4且k = 2,并且应当对于n = 5k = 2返回10。

1)最佳子结构
可以使用以下用于二项式系数的标准公式来递归计算C(n,k)的值。

C(n, k) = C(n-1, k-1) + C(n-1, k)
   C(n, 0) = C(n, n) = 1

以下是一个简单的递归实现,它仅遵循上述递归结构。

C++
// A naive recursive C++ implementation
#include 
using namespace std;
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    // Base Cases
    if (k > n)
        return 0;
    if (k == 0 || k == n)
        return 1;
 
    // Recur
    return binomialCoeff(n - 1, k - 1)
           + binomialCoeff(n - 1, k);
}
 
/* Driver code*/
int main()
{
    int n = 5, k = 2;
    cout << "Value of C(" << n << ", " << k << ") is "
         << binomialCoeff(n, k);
    return 0;
}
 
// This is code is contributed by rathbhupendra


C
// A Naive Recursive Implementation
#include 
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    // Base Cases
    if (k > n)
        return 0;
    if (k == 0 || k == n)
        return 1;
 
    // Recur
    return binomialCoeff(n - 1, k - 1)
           + binomialCoeff(n - 1, k);
}
 
/* Driver program to test above function*/
int main()
{
    int n = 5, k = 2;
    printf("Value of C(%d, %d) is %d ", n, k,
           binomialCoeff(n, k));
    return 0;
}


Java
// JAVA Code for Dynamic Programming |
// Set 9 (Binomial Coefficient)
import java.util.*;
 
class GFG {
 
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {
 
        // Base Cases
        if (k > n)
            return 0;
        if (k == 0 || k == n)
            return 1;
 
        // Recur
        return binomialCoeff(n - 1, k - 1)
            + binomialCoeff(n - 1, k);
    }
 
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        int n = 5, k = 2;
        System.out.printf("Value of C(%d, %d) is %d ", n, k,
                          binomialCoeff(n, k));
    }
}
 
// This code is contributed by Arnav Kr. Mandal.


Python
# A naive recursive Python implementation
 
 
def binomialCoeff(n, k):
 
    if k > n:
        return 0
    if k == 0 or k == n:
        return 1
 
    # Recursive Call
    return binomialCoeff(n-1, k-1) + binomialCoeff(n-1, k)
 
 
# Driver Program to test ht above function
n = 5
k = 2
print "Value of C(%d,%d) is (%d)" % (n, k,
                                     binomialCoeff(n, k))
 
# This code is contributed by Nikhil Kumar Singh (nickzuck_007)


C#
// C# Code for Dynamic Programming |
// Set 9 (Binomial Coefficient)
using System;
 
class GFG {
 
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {
 
        // Base Cases
        if (k > n)
            return 0;
        if (k == 0 || k == n)
            return 1;
 
        // Recur
        return binomialCoeff(n - 1, k - 1)
            + binomialCoeff(n - 1, k);
    }
 
    /* Driver program to test above function */
    public static void Main()
    {
        int n = 5, k = 2;
        Console.Write("Value of C(" + n + "," + k + ") is "
                      + binomialCoeff(n, k));
    }
}
 
// This code is contributed by Sam007.


PHP
 $n)
        return 0;
    if ($k==0 || $k==$n)
        return 1;
     
    // Recur
    return binomialCoeff($n - 1, $k - 1) +
               binomialCoeff($n - 1, $k);
}
 
    // Driver Code
    $n = 5;
    $k = 2;
    echo "Value of C","(",$n ,$k,") is "
               , binomialCoeff($n, $k);
 
// This code is contributed by aj_36
?>


Javascript


C++
// A Dynamic Programming based solution that uses
// table C[][] to calculate the Binomial Coefficient
#include 
using namespace std;
 
// Prototype of a utility function that
// returns minimum of two integers
int min(int a, int b);
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    int C[n + 1][k + 1];
    int i, j;
 
    // Caculate value of Binomial Coefficient
    // in bottom up manner
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= min(i, k); j++) {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
 
            // Calculate value using previously
            // stored values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
 
    return C[n][k];
}
 
// A utility function to return
// minimum of two integers
int min(int a, int b) { return (a < b) ? a : b; }
 
// Driver Code
int main()
{
    int n = 5, k = 2;
    cout << "Value of C[" << n << "][" << k << "] is "
         << binomialCoeff(n, k);
}
 
// This code is contributed by Shivi_Aggarwal


C
// A Dynamic Programming based solution
// that uses table C[][] to
// calculate the Binomial Coefficient
#include 
 
// Prototype of a utility function that
// returns minimum of two integers
int min(int a, int b);
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    int C[n + 1][k + 1];
    int i, j;
 
    // Caculate value of Binomial Coefficient
    // in bottom up manner
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= min(i, k); j++) {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
 
            // Calculate value using
            // previously stored values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
 
    return C[n][k];
}
 
// A utility function to return
// minimum of two integers
int min(int a, int b) { return (a < b) ? a : b; }
 
/* Drier program to test above function*/
int main()
{
    int n = 5, k = 2;
    printf("Value of C(%d, %d) is %d ", n, k,
           binomialCoeff(n, k));
    return 0;
}


Java
// A Dynamic Programming based
// solution that uses table C[][] to
// calculate the Binomial Coefficient
 
class BinomialCoefficient {
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {
        int C[][] = new int[n + 1][k + 1];
        int i, j;
 
        // Calculate  value of Binomial
        // Coefficient in bottom up manner
        for (i = 0; i <= n; i++) {
            for (j = 0; j <= min(i, k); j++) {
                // Base Cases
                if (j == 0 || j == i)
                    C[i][j] = 1;
 
                // Calculate value using
                // previously stored values
                else
                    C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
            }
        }
 
        return C[n][k];
    }
 
    // A utility function to return
    // minimum of two integers
    static int min(int a, int b) { return (a < b) ? a : b; }
 
    /* Driver program to test above function*/
    public static void main(String args[])
    {
        int n = 5, k = 2;
        System.out.println("Value of C(" + n + "," + k
                           + ") is " + binomialCoeff(n, k));
    }
}
/*This code is contributed by Rajat Mishra*/


Python
# A Dynamic Programming based Python
# Program that uses table C[][]
# to calculate the Binomial Coefficient
 
# Returns value of Binomial Coefficient C(n, k)
 
 
def binomialCoef(n, k):
    C = [[0 for x in range(k+1)] for x in range(n+1)]
 
    # Calculate value of Binomial
    # Coefficient in bottom up manner
    for i in range(n+1):
        for j in range(min(i, k)+1):
            # Base Cases
            if j == 0 or j == i:
                C[i][j] = 1
 
            # Calculate value using
            # previously stored values
            else:
                C[i][j] = C[i-1][j-1] + C[i-1][j]
 
    return C[n][k]
 
 
# Driver program to test above function
n = 5
k = 2
print("Value of C[" + str(n) + "][" + str(k) + "] is "
      + str(binomialCoef(n, k)))
 
# This code is contributed by Bhavya Jain


C#
// A Dynamic Programming based solution that
// uses table C[][] to calculate the Binomial
// Coefficient
using System;
 
class GFG {
 
    // Returns value of Binomial Coefficient
    // C(n, k)
    static int binomialCoeff(int n, int k)
    {
        int[, ] C = new int[n + 1, k + 1];
        int i, j;
 
        // Calculate value of Binomial
        // Coefficient in bottom up manner
        for (i = 0; i <= n; i++) {
            for (j = 0; j <= Math.Min(i, k); j++) {
                // Base Cases
                if (j == 0 || j == i)
                    C[i, j] = 1;
 
                // Calculate value using previously
                // stored values
                else
                    C[i, j] = C[i - 1, j - 1] + C[i - 1, j];
            }
        }
 
        return C[n, k];
    }
 
    // A utility function to return minimum
    // of two integers
    static int min(int a, int b) { return (a < b) ? a : b; }
 
    /* Driver program to test above function*/
    public static void Main()
    {
        int n = 5, k = 2;
        Console.WriteLine("Value of C(" + n + "," + k
                          + ") is " + binomialCoeff(n, k));
    }
}
 
// This code is contributed by anuj_67.


PHP


Javascript


C++
// C++ program for space optimized Dynamic Programming
// Solution of Binomial Coefficient
#include 
using namespace std;
 
int binomialCoeff(int n, int k)
{
    int C[k + 1];
    memset(C, 0, sizeof(C));
 
    C[0] = 1; // nC0 is 1
 
    for (int i = 1; i <= n; i++) {
        // Compute next row of pascal triangle using
        // the previous row
        for (int j = min(i, k); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
    return C[k];
}
 
/* Driver code*/
int main()
{
    int n = 5, k = 2;
    printf("Value of C(%d, %d) is %d ", n, k,
           binomialCoeff(n, k));
    return 0;
}


Java
// JAVA Code for Dynamic Programming |
// Set 9 (Binomial Coefficient)
import java.util.*;
 
class GFG {
 
    static int binomialCoeff(int n, int k)
    {
        int C[] = new int[k + 1];
 
        // nC0 is 1
        C[0] = 1;
 
        for (int i = 1; i <= n; i++) {
            // Compute next row of pascal
            // triangle using the previous row
            for (int j = Math.min(i, k); j > 0; j--)
                C[j] = C[j] + C[j - 1];
        }
        return C[k];
    }
 
    /* Driver code  */
    public static void main(String[] args)
    {
        int n = 5, k = 2;
        System.out.printf("Value of C(%d, %d) is %d ", n, k,
                          binomialCoeff(n, k));
    }
}


Python
# Python program for Optimized
# Dynamic Programming solution to
# Binomail Coefficient. This one
# uses the concept of pascal
# Triangle and less memory
 
 
def binomialCoeff(n, k):
 
    # Declaring an empty array
    C = [0 for i in xrange(k+1)]
    C[0] = 1  # since nC0 is 1
 
    for i in range(1, n+1):
 
        # Compute next row of pascal triangle using
        # the previous row
        j = min(i, k)
        while (j > 0):
            C[j] = C[j] + C[j-1]
            j -= 1
 
    return C[k]
 
 
# Driver Code
n = 5
k = 2
print "Value of C(%d,%d) is %d" % (n, k, binomialCoeff(n, k))
 
# This code is contribtued by Nikhil Kumar Singh(nickzuck_007)


C#
// C# Code for Dynamic Programming |
// Set 9 (Binomial Coefficient)
using System;
 
class GFG {
 
    static int binomialCoeff(int n, int k)
    {
        int[] C = new int[k + 1];
 
        // nC0 is 1
        C[0] = 1;
 
        for (int i = 1; i <= n; i++) {
            // Compute next row of pascal
            // triangle using the previous
            // row
            for (int j = Math.Min(i, k); j > 0; j--)
                C[j] = C[j] + C[j - 1];
        }
        return C[k];
    }
 
    /* Driver Code */
    public static void Main()
    {
        int n = 5, k = 2;
        Console.WriteLine("Value of C(" + n + " " + k
                          + ") is " + binomialCoeff(n, k));
    }
}
 
// This code is contribtued by anuj_67.


PHP
 0; $j--)
            $C[$j] = $C[$j] + $C[$j - 1];
    }
    return $C[$k];
}
 
// Driver Code
$n = 5; $k = 2;
echo "Value of C[$n, $k] is ".
        binomialCoeff($n, $k);
     
// This code is contributed by mits.
?>


Javascript


C++
// A Dynamic Programming based
// solution that uses
// table dp[][] to calculate
// the Binomial Coefficient
// A naive recursive approach
// with table C++ implementation
#include 
using namespace std;
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeffUtil(int n, int k, int** dp)
{
    // If value in lookup table then return
    if (dp[n][k] != -1) //    
        return dp[n][k];
 
    // store value in a table before return
    if (k == 0) {
        dp[n][k] = 1;
        return dp[n][k];
    }
     
    // store value in table before return
    if (k == n) {
        dp[n][k] = 1;
        return dp[n][k];
    }
     
    // save value in lookup table before return
    dp[n][k] = binomialCoeffUtil(n - 1, k - 1, dp) +
               binomialCoeffUtil(n - 1, k, dp);
    return dp[n][k];
}
 
int binomialCoeff(int n, int k)
{
    int** dp; // make a temporary lookup table
    dp = new int*[n + 1];
 
    // loop to create table dynamically
    for (int i = 0; i < (n + 1); i++) {
        dp[i] = new int[k + 1];
    }
 
    // nested loop to initialise the table with -1
    for (int i = 0; i < (n + 1); i++) {
        for (int j = 0; j < (k + 1); j++) {
            dp[i][j] = -1;
        }
    }
 
    return binomialCoeffUtil(n, k, dp);
}
 
/* Driver code*/
int main()
{
    int n = 5, k = 2;
    cout << "Value of C(" << n << ", " << k << ") is "
         << binomialCoeff(n, k) << endl;
    return 0;
}
 
// This is code is contributed by MOHAMMAD MUDASSIR


Java
// A Dynamic Programming based
// solution that uses
// table dp[][] to calculate
// the Binomial Coefficient
// A naive recursive approach
// with table Java implementation
import java.util.*;
class GFG{
 
// Returns value of Binomial
// Coefficient C(n, k)
static int binomialCoeffUtil(int n, int k,
                             Vector []dp)
{
  // If value in lookup table
  // then return
  if (dp[n].get(k) != -1)    
    return dp[n].get(k);
 
  // store value in a table
  // before return
  if (k == 0)
  {
    dp[n].add(k, 1);
    return dp[n].get(k);
  }
 
  // store value in table
  // before return
  if (k == n)
  {
    dp[n].add(k, 1);
    return dp[n].get(k);
  }
 
  // save value in lookup table
  // before return
  dp[n].add(k, binomialCoeffUtil(n - 1,
                                 k - 1, dp) +
               binomialCoeffUtil(n - 1,
                                 k, dp));
  return dp[n].get(k);
}
 
static int binomialCoeff(int n, int k)
{
  // Make a temporary lookup table
  Vector []dp = new Vector[n+1];
 
  // Loop to create table dynamically
  for (int i = 0; i < (n + 1); i++)
  {
    dp[i] = new Vector();
    for(int j = 0; j <= k; j++)
      dp[i].add(-1);
  }
  return binomialCoeffUtil(n, k, dp);
}
 
// Driver code
public static void main(String[] args)
{
  int n = 5, k = 2;
  System.out.print("Value of C(" + n +
                   ", " + k + ") is " +
                   binomialCoeff(n, k) + "\n");
}
}
 
// This code is contributed by Rajput-Ji


Python3
# A Dynamic Programming based solution
# that uses table dp[][] to calculate
# the Binomial Coefficient. A naive
# recursive approach with table
# Python3 implementation
 
# Returns value of Binomial
# Coefficient C(n, k)
def binomialCoeffUtil(n, k, dp):
     
    # If value in lookup table then return
    if dp[n][k] != -1:
        return dp[n][k]
 
    # Store value in a table before return
    if k == 0:
        dp[n][k] = 1
        return dp[n][k]
     
    # Store value in table before return
    if k == n:
        dp[n][k] = 1
        return dp[n][k]
     
    # Save value in lookup table before return
    dp[n][k] = (binomialCoeffUtil(n - 1, k - 1, dp) +
                binomialCoeffUtil(n - 1, k, dp))
                 
    return dp[n][k]
 
def binomialCoeff(n, k):
     
    # Make a temporary lookup table
    dp = [ [ -1 for y in range(k + 1) ]
                for x in range(n + 1) ]
 
    return binomialCoeffUtil(n, k, dp)
 
# Driver code
n = 5
k = 2
 
print("Value of C(" + str(n) +
               ", " + str(k) + ") is",
               binomialCoeff(n, k))
 
# This is code is contributed by Prateek Gupta


C#
// C# program for the
// above approach
 
// A Dynamic Programming based
// solution that uses
// table [,]dp to calculate
// the Binomial Coefficient
// A naive recursive approach
// with table C# implementation
using System;
using System.Collections.Generic;
class GFG{
 
// Returns value of Binomial
// Coefficient C(n, k)
static int binomialCoeffUtil(int n, int k,
                             List []dp)
{
  // If value in lookup table
  // then return
  if (dp[n][k] != -1)    
    return dp[n][k];
 
  // store value in a table
  // before return
  if (k == 0)
  {
    dp[n][k] = 1;
    return dp[n][k];
  }
 
  // store value in table
  // before return
  if (k == n)
  {
    dp[n][k] = 1;
    return dp[n][k];
  }
 
  // save value in lookup table
  // before return
  dp[n][k] = binomialCoeffUtil(n - 1,
                               k - 1, dp) +
             binomialCoeffUtil(n - 1,
                               k, dp);
  return dp[n][k];
}
 
static int binomialCoeff(int n, int k)
{
  // Make a temporary lookup table
  List []dp = new List[n + 1];
 
  // Loop to create table dynamically
  for (int i = 0; i < (n + 1); i++)
  {
    dp[i] = new List();
 
    for(int j = 0; j <= k; j++)
      dp[i].Add(-1);
  }
  return binomialCoeffUtil(n, k, dp);
}
 
// Driver code
public static void Main(String[] args)
{
  int n = 5, k = 2;
  Console.Write("Value of C(" + n +
                ", " + k + ") is " +
                binomialCoeff(n, k) + "\n");
}
}
 
// This code is contributed by 29AjayKumar


Java
import java.util.*;
class GFG
{
    static int gcd(int a, int b) // function to find gcd of two numbers in O(log(min(a,b)))
    {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    static int nCr(int n, int r)
    {
        if(r>n) // base case
            return 0;
        if(r>n-r) // C(n,r) = C(n,n-r) better time complexity for lesser r value
            r = n-r;
        int mod = 1000000007;
        int[] arr = new int[r]; // array of elements from n-r+1 to n
        for(int i=n-r+1; i<=n; i++)
        {
            arr[i+r-n-1] = i;
        }
        long ans = 1;
        for(int k=1;k1
        {
            int j=0, i=k;
            while(j1)
                {
                    arr[j] /= x; // if gcd>1, divide both by gcd
                    i /= x;
                }
                if(i==1)
                    break; // if i becomes 1, no need to search arr
                j += 1;
            }
        }
        for(int i : arr) // single pass to multiply the numerator
            ans = (ans*i)%mod;
        return (int)ans;
    }
    // Driver code
    public static void main(String[] args)
    {
        int n = 5, r = 2;
        System.out.print("Value of C(" +  n+ ", " +  r+ ") is "
             +nCr(n, r) +"\n");
    }
}
// This code is contributed by Gautam Wadhwani


Python3
import math
class GFG:
    def nCr(self, n, r):
        def gcd(a,b): # function to find gcd of two numbers in O(log(min(a,b)))
            if b==0: # base case
                return a
            return gcd(b,a%b)
        if r>n:
            return 0
        if r>n-r: # C(n,r) = C(n,n-r) better time complexity for lesser r value
            r = n-r
        mod = 10**9 + 7
        arr = list(range(n-r+1,n+1)) # array of elements from n-r+1 to n
        ans = 1
        for i in range(1,r+1): # for numbers from 1 to r find arr[j] such that gcd(i,arr[j])>1
            j=0
            while j1:
                    arr[j] //= x # if gcd>1, divide both by gcd
                    i //= x
                if arr[j]==1: # if element becomes 1, its of no use anymore so delete from arr
                    del arr[j]
                    j -= 1
                if i==1:
                    break # if i becomes 1, no need to search arr
                j += 1
        for i in arr: # single pass to multiply the numerator
            ans = (ans*i)%mod
        return ans
     # Driver code
n = 5
k = 2
ob = GFG()
print("Value of C(" + str(n) +
               ", " + str(k) + ") is",
               ob.nCr(n, k))
  
# This is code is contributed by Gautam Wadhwani


Java
import java.util.*;
class GFG {
   
    // pow(base,exp,mod) is used to find
    // (base^exp)%mod fast -> O(log(exp))
    static long pow(long b, long exp, long mod)
    {
        long ret = 1;
        while (exp > 0) {
            if ((exp & 1) > 0)
                ret = (ret * b) % mod;
            b = (b * b) % mod;
            exp >>= 1;
        }
        return ret;
    }
    static int nCr(int n, int r)
    {
        if (r > n) // base case
            return 0;
       
        // C(n,r) = C(n,n-r) Complexity for
        // this code is lesser for lower n-r
        if (n - r > r)
            r = n - r;
       
        // list to smallest prime factor
        // of each number from 1 to n
        int[] SPF = new int[n + 1];
       
        // set smallest prime factor of each
        // number as itself
        for (int i = 1; i <= n; i++)
            SPF[i] = i;
       
        // set smallest prime factor of all
        // even numbers as 2
        for (int i = 4; i <= n; i += 2)
            SPF[i] = 2;
       
        for (int i = 3; i * i < n + 1; i += 2)
        {
             
            // Check if i is prime
            if (SPF[i] == i)
            {
               
                // All multiples of i are
                // composite (and divisible by
                // i) so add i to their prime
                // factorization getpow(j,i)
                // times
                for (int j = i * i; j < n + 1; j += i)
                    if (SPF[j] == j) {
                        SPF[j] = i;
                    }
            }
        }
       
       // Hash Map to store power of
       // each prime in C(n,r)
       Map prime_pow
            = new HashMap<>();
       
        // For numerator count frequency of each prime factor
        for (int i = r + 1; i < n + 1; i++)
        {
            int t = i;
             
            // Recursive division to find
            // prime factorization of i
            while (t > 1)
            {
                prime_pow.put(SPF[t],
                    prime_pow.getOrDefault(SPF[t], 0) + 1);
                t /= SPF[t];
            }
        }
       
        // For denominator subtract the power of
        // each prime factor
        for (int i = 1; i < n - r + 1; i++)
        {
            int t = i;
           
            // Recursive division to find
            // prime factorization of i
            while (t > 1)
            {
                prime_pow.put(SPF[t],
                              prime_pow.get(SPF[t]) - 1);
                t /= SPF[t];
            }
        }
       
        // long because mod is large and a%mod
        // * b%mod can overflow int
        long ans = 1, mod = 1000000007;
       
        // use (a*b)%mod = (a%mod * b%mod)%mod
        for (int i : prime_pow.keySet())
           
            // pow(base,exp,mod) is used to
            // find (base^exp)%mod fast
            ans = (ans * pow(i, prime_pow.get(i), mod))
                  % mod;
        return (int)ans;
    }
   
    // Driver code
    public static void main(String[] args)
    {
        int n = 5, r = 2;
        System.out.print("Value of C(" + n + ", " + r
                         + ") is " + nCr(n, r) + "\n");
    }
}
// This code is contributed by Gautam Wadhwani


Python3
# Python code for the above approach
import math
 
class GFG:
    def nCr(self, n, r):
       
        # Base case
        if r > n: 
            return 0
           
        # C(n,r) = C(n,n-r) Complexity for this
        # code is lesser for lower n-r
        if n - r > r: 
            r = n - r
             
        # List to store smallest prime factor
        # of every number from 1 to n
        SPF = [i for i in range(n+1)]
        for i in range(4, n+1, 2):
           
            # set smallest prime factor of
            # all even numbers as 2
            SPF[i] = 2
     
        for i in range(3, n+1, 2): 
         
            if i*i > n:
                break
               
            # Check if i is prime
            if SPF[i] == i: 
                 
                # All multiples of i are composite
                # (and divisible by i) so add i to
                # their prime factorization getpow(j,i) times
                for j in range(i*i, n+1, i):
                    if SPF[j] == j:
                       
                        # set smallest prime factor
                        # of j to i only if it is
                        # not previously set
                        SPF[j] = i
         
         # dictionary to store power of each prime in C(n,r)
        prime_pow = {} 
         
        # For numerator count frequency
        # of each prime factor
        for i in range(r+1, n+1):
            t = i
             
            # Recursive division to
            # find prime factorization of i
            while t > 1:
                if not SPF[t] in prime_pow:
                    prime_pow[SPF[t]] = 1
                else:
                    prime_pow[SPF[t]] += 1
                t //= SPF[t]
         
        # For denominator subtract the
        # power of each prime factor
        for i in range(1, n-r+1): 
            t = i
             
            # Recursive division to
            # find prime factorization of i
            while t > 1: 
                prime_pow[SPF[t]] -= 1
                t //= SPF[t]
        ans = 1
        mod = 10**9 + 7
         
         # Use (a*b)%mod = (a%mod * b%mod)%mod
        for i in prime_pow:
           
            # pow(base,exp,mod) is used to
            # find (base^exp)%mod fast
            ans = (ans*pow(i, prime_pow[i], mod)) % mod
        return ans
 
 
# Driver code
n = 5
k = 2
ob = GFG()
print("Value of C(" + str(n) +
      ", " + str(k) + ") is",
      ob.nCr(n, k))
 
# This is code is contributed by Gautam Wadhwani


C++
// C++ program for the above approach
#include
using namespace std;
 
// Function to find binomial
// coefficient
int binomialCoeff(int n, int r)
{
 
    if (r > n)
        return 0;
    long long int m = 1000000007;
    long long int inv[r + 1] = { 0 };
    inv[1] = 1;
 
    // Getting the modular inversion
    // for all the numbers
    // from 2 to r with respect to m
    // here m = 1000000007
    for (int i = 2; i <= r; i++) {
        inv[i] = m - (m / i) * inv[m % i] % m;
    }
 
    int ans = 1;
 
    // for 1/(r!) part
    for (int i = 2; i <= r; i++) {
        ans = ((ans % m) * (inv[i] % m)) % m;
    }
 
    // for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for (int i = n; i >= (n - r + 1); i--) {
        ans = ((ans % m) * (i % m)) % m;
    }
    return ans;
}
 
/* Driver code*/
int main()
{
    int n = 5, r = 2;
    cout << "Value of C(" << n << ", " << r << ") is "
         << binomialCoeff(n, r) << endl;
    return 0;
}


Java
// JAVA program for the above approach
import java.util.*;
class GFG
{
 
// Function to find binomial
// coefficient
static int binomialCoeff(int n, int r)
{
 
    if (r > n)
    return 0;
    long  m = 1000000007;
    long  inv[] = new long[r + 1];
    inv[1] = 1;
 
    // Getting the modular inversion
    // for all the numbers
    // from 2 to r with respect to m
    // here m = 1000000007
    for (int i = 2; i <= r; i++) {
        inv[i] = m - (m / i) * inv[(int) (m % i)] % m;
    }
 
    int ans = 1;
 
    // for 1/(r!) part
    for (int i = 2; i <= r; i++) {
        ans = (int) (((ans % m) * (inv[i] % m)) % m);
    }
 
    // for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for (int i = n; i >= (n - r + 1); i--) {
        ans = (int) (((ans % m) * (i % m)) % m);
    }
    return ans;
}
 
/* Driver code*/
public static void main(String[] args)
{
    int n = 5, r = 2;
    System.out.print("Value of C(" +  n+ ", " +  r+ ") is "
         +binomialCoeff(n, r) +"\n");
}
}
 
// This code contributed by Rajput-Ji


Python3
# Python3 program for the above approach
 
# Function to find binomial
# coefficient
def binomialCoeff(n, r):
     
    if (r > n):
        return 0
         
    m = 1000000007
    inv = [0 for i in range(r + 1)]
    inv[1] = 1
 
    # Getting the modular inversion
    # for all the numbers
    # from 2 to r with respect to m
    # here m = 1000000007
    for i in range(2, r + 1):
        inv[i] = m - (m // i) * inv[m % i] % m
 
    ans = 1
 
    # for 1/(r!) part
    for i in range(2, r + 1):
        ans = ((ans % m) * (inv[i] % m)) % m
 
    # for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for i in range(n, n - r, -1):
        ans = ((ans % m) * (i % m)) % m
         
    return ans
 
# Driver code
n = 5
r = 2
 
print("Value of C(" ,n , ", " , r ,
      ") is ",binomialCoeff(n, r))
 
# This code is contributed by rohan07


C#
// C# program for the above approach
using System;
 
public class GFG
{
 
// Function to find binomial
// coefficient
static int binomialCoeff(int n, int r)
{
 
    if (r > n)
    return 0;
    long  m = 1000000007;
    long  []inv = new long[r + 1];
    inv[1] = 1;
 
    // Getting the modular inversion
    // for all the numbers
    // from 2 to r with respect to m
    // here m = 1000000007
    for (int i = 2; i <= r; i++) {
        inv[i] = m - (m / i) * inv[(int) (m % i)] % m;
    }
 
    int ans = 1;
 
    // for 1/(r!) part
    for (int i = 2; i <= r; i++) {
        ans = (int) (((ans % m) * (inv[i] % m)) % m);
    }
 
    // for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for (int i = n; i >= (n - r + 1); i--) {
        ans = (int) (((ans % m) * (i % m)) % m);
    }
    return ans;
}
 
/* Driver code*/
public static void Main(String[] args)
{
    int n = 5, r = 2;
    Console.Write("Value of C(" +  n+ ", " +  r+ ") is "
         +binomialCoeff(n, r) +"\n");
}
}
 
 
 
// This code is contributed by 29AjayKumar


输出
Value of C(5, 2) is 10

2)重叠子问题
应该注意的是,上述函数一次又一次地计算相同的子问题。有关n = 5和k = 2,请参见下面的递归树。函数C(3,1)被调用两次。对于较大的n值,将存在许多常见的子问题。

C(5,2)的二项式系数递归树

由于再次调用了相同的子问题,因此此问题具有“重叠子问题”属性。因此,二项式系数问题具有动态规划问题的两个属性(请参阅此内容)。像其他典型的动态编程(DP)问题一样,可以通过自下而上的方式构造临时2D数组C [] []来避免相同子问题的重新计算。以下是基于动态编程的实现。

C++

// A Dynamic Programming based solution that uses
// table C[][] to calculate the Binomial Coefficient
#include 
using namespace std;
 
// Prototype of a utility function that
// returns minimum of two integers
int min(int a, int b);
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    int C[n + 1][k + 1];
    int i, j;
 
    // Caculate value of Binomial Coefficient
    // in bottom up manner
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= min(i, k); j++) {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
 
            // Calculate value using previously
            // stored values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
 
    return C[n][k];
}
 
// A utility function to return
// minimum of two integers
int min(int a, int b) { return (a < b) ? a : b; }
 
// Driver Code
int main()
{
    int n = 5, k = 2;
    cout << "Value of C[" << n << "][" << k << "] is "
         << binomialCoeff(n, k);
}
 
// This code is contributed by Shivi_Aggarwal

C

// A Dynamic Programming based solution
// that uses table C[][] to
// calculate the Binomial Coefficient
#include 
 
// Prototype of a utility function that
// returns minimum of two integers
int min(int a, int b);
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    int C[n + 1][k + 1];
    int i, j;
 
    // Caculate value of Binomial Coefficient
    // in bottom up manner
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= min(i, k); j++) {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
 
            // Calculate value using
            // previously stored values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
 
    return C[n][k];
}
 
// A utility function to return
// minimum of two integers
int min(int a, int b) { return (a < b) ? a : b; }
 
/* Drier program to test above function*/
int main()
{
    int n = 5, k = 2;
    printf("Value of C(%d, %d) is %d ", n, k,
           binomialCoeff(n, k));
    return 0;
}

Java

// A Dynamic Programming based
// solution that uses table C[][] to
// calculate the Binomial Coefficient
 
class BinomialCoefficient {
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {
        int C[][] = new int[n + 1][k + 1];
        int i, j;
 
        // Calculate  value of Binomial
        // Coefficient in bottom up manner
        for (i = 0; i <= n; i++) {
            for (j = 0; j <= min(i, k); j++) {
                // Base Cases
                if (j == 0 || j == i)
                    C[i][j] = 1;
 
                // Calculate value using
                // previously stored values
                else
                    C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
            }
        }
 
        return C[n][k];
    }
 
    // A utility function to return
    // minimum of two integers
    static int min(int a, int b) { return (a < b) ? a : b; }
 
    /* Driver program to test above function*/
    public static void main(String args[])
    {
        int n = 5, k = 2;
        System.out.println("Value of C(" + n + "," + k
                           + ") is " + binomialCoeff(n, k));
    }
}
/*This code is contributed by Rajat Mishra*/

Python

# A Dynamic Programming based Python
# Program that uses table C[][]
# to calculate the Binomial Coefficient
 
# Returns value of Binomial Coefficient C(n, k)
 
 
def binomialCoef(n, k):
    C = [[0 for x in range(k+1)] for x in range(n+1)]
 
    # Calculate value of Binomial
    # Coefficient in bottom up manner
    for i in range(n+1):
        for j in range(min(i, k)+1):
            # Base Cases
            if j == 0 or j == i:
                C[i][j] = 1
 
            # Calculate value using
            # previously stored values
            else:
                C[i][j] = C[i-1][j-1] + C[i-1][j]
 
    return C[n][k]
 
 
# Driver program to test above function
n = 5
k = 2
print("Value of C[" + str(n) + "][" + str(k) + "] is "
      + str(binomialCoef(n, k)))
 
# This code is contributed by Bhavya Jain

C#

// A Dynamic Programming based solution that
// uses table C[][] to calculate the Binomial
// Coefficient
using System;
 
class GFG {
 
    // Returns value of Binomial Coefficient
    // C(n, k)
    static int binomialCoeff(int n, int k)
    {
        int[, ] C = new int[n + 1, k + 1];
        int i, j;
 
        // Calculate value of Binomial
        // Coefficient in bottom up manner
        for (i = 0; i <= n; i++) {
            for (j = 0; j <= Math.Min(i, k); j++) {
                // Base Cases
                if (j == 0 || j == i)
                    C[i, j] = 1;
 
                // Calculate value using previously
                // stored values
                else
                    C[i, j] = C[i - 1, j - 1] + C[i - 1, j];
            }
        }
 
        return C[n, k];
    }
 
    // A utility function to return minimum
    // of two integers
    static int min(int a, int b) { return (a < b) ? a : b; }
 
    /* Driver program to test above function*/
    public static void Main()
    {
        int n = 5, k = 2;
        Console.WriteLine("Value of C(" + n + "," + k
                          + ") is " + binomialCoeff(n, k));
    }
}
 
// This code is contributed by anuj_67.

的PHP


Java脚本


输出
Value of C[5][2] is 10

时间复杂度: O(n * k)
辅助空间: O(n * k)

以下是上述代码的空间优化版本。以下代码仅使用O(k)。感谢AK建议使用此方法。

C++

// C++ program for space optimized Dynamic Programming
// Solution of Binomial Coefficient
#include 
using namespace std;
 
int binomialCoeff(int n, int k)
{
    int C[k + 1];
    memset(C, 0, sizeof(C));
 
    C[0] = 1; // nC0 is 1
 
    for (int i = 1; i <= n; i++) {
        // Compute next row of pascal triangle using
        // the previous row
        for (int j = min(i, k); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
    return C[k];
}
 
/* Driver code*/
int main()
{
    int n = 5, k = 2;
    printf("Value of C(%d, %d) is %d ", n, k,
           binomialCoeff(n, k));
    return 0;
}

Java

// JAVA Code for Dynamic Programming |
// Set 9 (Binomial Coefficient)
import java.util.*;
 
class GFG {
 
    static int binomialCoeff(int n, int k)
    {
        int C[] = new int[k + 1];
 
        // nC0 is 1
        C[0] = 1;
 
        for (int i = 1; i <= n; i++) {
            // Compute next row of pascal
            // triangle using the previous row
            for (int j = Math.min(i, k); j > 0; j--)
                C[j] = C[j] + C[j - 1];
        }
        return C[k];
    }
 
    /* Driver code  */
    public static void main(String[] args)
    {
        int n = 5, k = 2;
        System.out.printf("Value of C(%d, %d) is %d ", n, k,
                          binomialCoeff(n, k));
    }
}

Python

# Python program for Optimized
# Dynamic Programming solution to
# Binomail Coefficient. This one
# uses the concept of pascal
# Triangle and less memory
 
 
def binomialCoeff(n, k):
 
    # Declaring an empty array
    C = [0 for i in xrange(k+1)]
    C[0] = 1  # since nC0 is 1
 
    for i in range(1, n+1):
 
        # Compute next row of pascal triangle using
        # the previous row
        j = min(i, k)
        while (j > 0):
            C[j] = C[j] + C[j-1]
            j -= 1
 
    return C[k]
 
 
# Driver Code
n = 5
k = 2
print "Value of C(%d,%d) is %d" % (n, k, binomialCoeff(n, k))
 
# This code is contribtued by Nikhil Kumar Singh(nickzuck_007)

C#

// C# Code for Dynamic Programming |
// Set 9 (Binomial Coefficient)
using System;
 
class GFG {
 
    static int binomialCoeff(int n, int k)
    {
        int[] C = new int[k + 1];
 
        // nC0 is 1
        C[0] = 1;
 
        for (int i = 1; i <= n; i++) {
            // Compute next row of pascal
            // triangle using the previous
            // row
            for (int j = Math.Min(i, k); j > 0; j--)
                C[j] = C[j] + C[j - 1];
        }
        return C[k];
    }
 
    /* Driver Code */
    public static void Main()
    {
        int n = 5, k = 2;
        Console.WriteLine("Value of C(" + n + " " + k
                          + ") is " + binomialCoeff(n, k));
    }
}
 
// This code is contribtued by anuj_67.

的PHP

 0; $j--)
            $C[$j] = $C[$j] + $C[$j - 1];
    }
    return $C[$k];
}
 
// Driver Code
$n = 5; $k = 2;
echo "Value of C[$n, $k] is ".
        binomialCoeff($n, $k);
     
// This code is contributed by mits.
?>

Java脚本


输出

Value of C(5, 2) is 10 

时间复杂度: O(n * k)
辅助空间: O(k)

解释:
1 ========== >> n = 0,C(0,0)= 1
1–1 ======== >>>> n = 1,C(1,0)= 1,C(1,1)= 1
1–2–1 ====== >> n = 2,C(2,0)= 1,C(2,1)= 2,C(2,2)= 1
1–3–3–1 ==== >> n = 3,C(3,0)= 1,C(3,1)= 3,C(3,2)= 3,C(3,3) = 1
1–4–6–4–1 == >> n = 4,C(4,0)= 1,C(4,1)= 4,C(4,2)= 6,C(4,3) = 4,C(4,4)= 1
因此,这里的每个i循环都使用第(i-1)行建立第i行pascal三角形
在任何时候,数组C的每个元素都会有一个值(零或更大),并且在下一次迭代中,这些元素的值来自上一次迭代。
在声明中,
C [j] = C [j] + C [j-1]
右侧表示来自上一迭代的值(Pascal三角形的一行取决于上一行)。左侧代表此语句将获得的当前迭代的值。

Let's say we want to calculate C(4, 3), 
i.e. n=4, k=3:

All elements of array C of size 4 (k+1) are
initialized to ZERO.

i.e. C[0] = C[1] = C[2] = C[3] = C[4] = 0;
Then C[0] is set to 1

For i = 1:
C[1] = C[1] + C[0] = 0 + 1 = 1 ==>> C(1,1) = 1

For i = 2:
C[2] = C[2] + C[1] = 0 + 1 = 1 ==>> C(2,2) = 1
C[1] = C[1] + C[0] = 1 + 1 = 2 ==>> C(2,1) = 2

For i=3:
C[3] = C[3] + C[2] = 0 + 1 = 1 ==>> C(3,3) = 1
C[2] = C[2] + C[1] = 1 + 2 = 3 ==>> C(3,2) = 3
C[1] = C[1] + C[0] = 2 + 1 = 3 ==>> C(3,1) = 3

For i=4:
C[4] = C[4] + C[3] = 0 + 1 = 1 ==>> C(4,4) = 1
C[3] = C[3] + C[2] = 1 + 3 = 4 ==>> C(4,3) = 4
C[2] = C[2] + C[1] = 3 + 3 = 6 ==>> C(4,2) = 6
C[1] = C[1] + C[0] = 3 + 1 = 4 ==>> C(4,1) = 4

C(4,3) = 4 is would be the answer in our example.

记忆方法:想法是创建一个查找表并遵循递归自上而下的方法。在计算任何值之前,我们检查它是否已经在查找表中。如果是,我们返回值。否则,我们计算该值并将其存储在查找表中。以下是动态编程的自上而下方法来查找二项式系数的值。

C++

// A Dynamic Programming based
// solution that uses
// table dp[][] to calculate
// the Binomial Coefficient
// A naive recursive approach
// with table C++ implementation
#include 
using namespace std;
 
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeffUtil(int n, int k, int** dp)
{
    // If value in lookup table then return
    if (dp[n][k] != -1) //    
        return dp[n][k];
 
    // store value in a table before return
    if (k == 0) {
        dp[n][k] = 1;
        return dp[n][k];
    }
     
    // store value in table before return
    if (k == n) {
        dp[n][k] = 1;
        return dp[n][k];
    }
     
    // save value in lookup table before return
    dp[n][k] = binomialCoeffUtil(n - 1, k - 1, dp) +
               binomialCoeffUtil(n - 1, k, dp);
    return dp[n][k];
}
 
int binomialCoeff(int n, int k)
{
    int** dp; // make a temporary lookup table
    dp = new int*[n + 1];
 
    // loop to create table dynamically
    for (int i = 0; i < (n + 1); i++) {
        dp[i] = new int[k + 1];
    }
 
    // nested loop to initialise the table with -1
    for (int i = 0; i < (n + 1); i++) {
        for (int j = 0; j < (k + 1); j++) {
            dp[i][j] = -1;
        }
    }
 
    return binomialCoeffUtil(n, k, dp);
}
 
/* Driver code*/
int main()
{
    int n = 5, k = 2;
    cout << "Value of C(" << n << ", " << k << ") is "
         << binomialCoeff(n, k) << endl;
    return 0;
}
 
// This is code is contributed by MOHAMMAD MUDASSIR

Java

// A Dynamic Programming based
// solution that uses
// table dp[][] to calculate
// the Binomial Coefficient
// A naive recursive approach
// with table Java implementation
import java.util.*;
class GFG{
 
// Returns value of Binomial
// Coefficient C(n, k)
static int binomialCoeffUtil(int n, int k,
                             Vector []dp)
{
  // If value in lookup table
  // then return
  if (dp[n].get(k) != -1)    
    return dp[n].get(k);
 
  // store value in a table
  // before return
  if (k == 0)
  {
    dp[n].add(k, 1);
    return dp[n].get(k);
  }
 
  // store value in table
  // before return
  if (k == n)
  {
    dp[n].add(k, 1);
    return dp[n].get(k);
  }
 
  // save value in lookup table
  // before return
  dp[n].add(k, binomialCoeffUtil(n - 1,
                                 k - 1, dp) +
               binomialCoeffUtil(n - 1,
                                 k, dp));
  return dp[n].get(k);
}
 
static int binomialCoeff(int n, int k)
{
  // Make a temporary lookup table
  Vector []dp = new Vector[n+1];
 
  // Loop to create table dynamically
  for (int i = 0; i < (n + 1); i++)
  {
    dp[i] = new Vector();
    for(int j = 0; j <= k; j++)
      dp[i].add(-1);
  }
  return binomialCoeffUtil(n, k, dp);
}
 
// Driver code
public static void main(String[] args)
{
  int n = 5, k = 2;
  System.out.print("Value of C(" + n +
                   ", " + k + ") is " +
                   binomialCoeff(n, k) + "\n");
}
}
 
// This code is contributed by Rajput-Ji

Python3

# A Dynamic Programming based solution
# that uses table dp[][] to calculate
# the Binomial Coefficient. A naive
# recursive approach with table
# Python3 implementation
 
# Returns value of Binomial
# Coefficient C(n, k)
def binomialCoeffUtil(n, k, dp):
     
    # If value in lookup table then return
    if dp[n][k] != -1:
        return dp[n][k]
 
    # Store value in a table before return
    if k == 0:
        dp[n][k] = 1
        return dp[n][k]
     
    # Store value in table before return
    if k == n:
        dp[n][k] = 1
        return dp[n][k]
     
    # Save value in lookup table before return
    dp[n][k] = (binomialCoeffUtil(n - 1, k - 1, dp) +
                binomialCoeffUtil(n - 1, k, dp))
                 
    return dp[n][k]
 
def binomialCoeff(n, k):
     
    # Make a temporary lookup table
    dp = [ [ -1 for y in range(k + 1) ]
                for x in range(n + 1) ]
 
    return binomialCoeffUtil(n, k, dp)
 
# Driver code
n = 5
k = 2
 
print("Value of C(" + str(n) +
               ", " + str(k) + ") is",
               binomialCoeff(n, k))
 
# This is code is contributed by Prateek Gupta

C#

// C# program for the
// above approach
 
// A Dynamic Programming based
// solution that uses
// table [,]dp to calculate
// the Binomial Coefficient
// A naive recursive approach
// with table C# implementation
using System;
using System.Collections.Generic;
class GFG{
 
// Returns value of Binomial
// Coefficient C(n, k)
static int binomialCoeffUtil(int n, int k,
                             List []dp)
{
  // If value in lookup table
  // then return
  if (dp[n][k] != -1)    
    return dp[n][k];
 
  // store value in a table
  // before return
  if (k == 0)
  {
    dp[n][k] = 1;
    return dp[n][k];
  }
 
  // store value in table
  // before return
  if (k == n)
  {
    dp[n][k] = 1;
    return dp[n][k];
  }
 
  // save value in lookup table
  // before return
  dp[n][k] = binomialCoeffUtil(n - 1,
                               k - 1, dp) +
             binomialCoeffUtil(n - 1,
                               k, dp);
  return dp[n][k];
}
 
static int binomialCoeff(int n, int k)
{
  // Make a temporary lookup table
  List []dp = new List[n + 1];
 
  // Loop to create table dynamically
  for (int i = 0; i < (n + 1); i++)
  {
    dp[i] = new List();
 
    for(int j = 0; j <= k; j++)
      dp[i].Add(-1);
  }
  return binomialCoeffUtil(n, k, dp);
}
 
// Driver code
public static void Main(String[] args)
{
  int n = 5, k = 2;
  Console.Write("Value of C(" + n +
                ", " + k + ") is " +
                binomialCoeff(n, k) + "\n");
}
}
 
// This code is contributed by 29AjayKumar
输出
Value of C(5, 2) is 10

消除分子和分母之间的因子:

nCr =(n-r + 1)*(n-r + 2)* …. * n /(r!)

创建一个由n-r + 1到n的数字组成的数组arr,其大小为r。由于nCr始终是整数,因此分母中的所有数字都应与分子乘积(由arr表示)抵消。

对于i = 1到i = r,

搜索arr,如果arr [j]和我的gcd> 1,则将其除以gcd,当我变为1时,停止搜索

现在,答案只是arr的乘积,可以使用单次通过找到其值mod 10 ^ 9 + 7,公式使用(a * b)%mod =(a%mod * b%mod)%mod

Java

import java.util.*;
class GFG
{
    static int gcd(int a, int b) // function to find gcd of two numbers in O(log(min(a,b)))
    {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    static int nCr(int n, int r)
    {
        if(r>n) // base case
            return 0;
        if(r>n-r) // C(n,r) = C(n,n-r) better time complexity for lesser r value
            r = n-r;
        int mod = 1000000007;
        int[] arr = new int[r]; // array of elements from n-r+1 to n
        for(int i=n-r+1; i<=n; i++)
        {
            arr[i+r-n-1] = i;
        }
        long ans = 1;
        for(int k=1;k1
        {
            int j=0, i=k;
            while(j1)
                {
                    arr[j] /= x; // if gcd>1, divide both by gcd
                    i /= x;
                }
                if(i==1)
                    break; // if i becomes 1, no need to search arr
                j += 1;
            }
        }
        for(int i : arr) // single pass to multiply the numerator
            ans = (ans*i)%mod;
        return (int)ans;
    }
    // Driver code
    public static void main(String[] args)
    {
        int n = 5, r = 2;
        System.out.print("Value of C(" +  n+ ", " +  r+ ") is "
             +nCr(n, r) +"\n");
    }
}
// This code is contributed by Gautam Wadhwani

Python3

import math
class GFG:
    def nCr(self, n, r):
        def gcd(a,b): # function to find gcd of two numbers in O(log(min(a,b)))
            if b==0: # base case
                return a
            return gcd(b,a%b)
        if r>n:
            return 0
        if r>n-r: # C(n,r) = C(n,n-r) better time complexity for lesser r value
            r = n-r
        mod = 10**9 + 7
        arr = list(range(n-r+1,n+1)) # array of elements from n-r+1 to n
        ans = 1
        for i in range(1,r+1): # for numbers from 1 to r find arr[j] such that gcd(i,arr[j])>1
            j=0
            while j1:
                    arr[j] //= x # if gcd>1, divide both by gcd
                    i //= x
                if arr[j]==1: # if element becomes 1, its of no use anymore so delete from arr
                    del arr[j]
                    j -= 1
                if i==1:
                    break # if i becomes 1, no need to search arr
                j += 1
        for i in arr: # single pass to multiply the numerator
            ans = (ans*i)%mod
        return ans
     # Driver code
n = 5
k = 2
ob = GFG()
print("Value of C(" + str(n) +
               ", " + str(k) + ") is",
               ob.nCr(n, k))
  
# This is code is contributed by Gautam Wadhwani
输出
Value of C(5, 2) is 10

时间复杂度: O((min(r,nr)^ 2)* log(n)),当n >> r或n >>(nr)时有用

辅助空间: O(min(r,nr))

在对数时间查看此以获取GCD

使用Eratosthenes筛子对从1到n的每个数进行素数分解:

1.创建大小为n + 1到每个从1到n的最小素数的数组SPF

Set SPF[i] = i for all i = 1 to i = n

2.使用Eratosthenes筛:

for i = 2 to i = n:
    if i is prime,
       for all multiples j of i, j<=n:
           if SPF[j] equals j, set SPF[j] = i

3.一次,我们知道从1到n的每个数字的SPF,我们可以使用SPF递归除法,直到O(log(n))时间在O(log(n))时间内找到从1到n的任何数字的素因式分解,直到数字变为1

Now, nCr  =  (n-r+1)*(r+2)* ... *(n) / (r)!

4.创建一个字典(或哈希图)以存储nCr实际值的质数分解中每个质数的频率。

5.因此,只需以nCr为单位计算每个素数的频率,然后将它们乘以其频率的乘方即可。

6.对于分子,通过i = n-r + 1迭代到i = n,对于i的所有素数,将其频率存储在字典中。

( prime_pow[prime_factor] += freq_in_i )

7.对于分母,遍历i = 1到i = r,然后减去频率而不是相加。

8.现在,遍历字典并将答案乘以(prime ^ prime_pow [prime])%(10 ^ 9 + 7)

ans = (ans * pow(prime, prime_pow[prime], mod) ) % mod

Java

import java.util.*;
class GFG {
   
    // pow(base,exp,mod) is used to find
    // (base^exp)%mod fast -> O(log(exp))
    static long pow(long b, long exp, long mod)
    {
        long ret = 1;
        while (exp > 0) {
            if ((exp & 1) > 0)
                ret = (ret * b) % mod;
            b = (b * b) % mod;
            exp >>= 1;
        }
        return ret;
    }
    static int nCr(int n, int r)
    {
        if (r > n) // base case
            return 0;
       
        // C(n,r) = C(n,n-r) Complexity for
        // this code is lesser for lower n-r
        if (n - r > r)
            r = n - r;
       
        // list to smallest prime factor
        // of each number from 1 to n
        int[] SPF = new int[n + 1];
       
        // set smallest prime factor of each
        // number as itself
        for (int i = 1; i <= n; i++)
            SPF[i] = i;
       
        // set smallest prime factor of all
        // even numbers as 2
        for (int i = 4; i <= n; i += 2)
            SPF[i] = 2;
       
        for (int i = 3; i * i < n + 1; i += 2)
        {
             
            // Check if i is prime
            if (SPF[i] == i)
            {
               
                // All multiples of i are
                // composite (and divisible by
                // i) so add i to their prime
                // factorization getpow(j,i)
                // times
                for (int j = i * i; j < n + 1; j += i)
                    if (SPF[j] == j) {
                        SPF[j] = i;
                    }
            }
        }
       
       // Hash Map to store power of
       // each prime in C(n,r)
       Map prime_pow
            = new HashMap<>();
       
        // For numerator count frequency of each prime factor
        for (int i = r + 1; i < n + 1; i++)
        {
            int t = i;
             
            // Recursive division to find
            // prime factorization of i
            while (t > 1)
            {
                prime_pow.put(SPF[t],
                    prime_pow.getOrDefault(SPF[t], 0) + 1);
                t /= SPF[t];
            }
        }
       
        // For denominator subtract the power of
        // each prime factor
        for (int i = 1; i < n - r + 1; i++)
        {
            int t = i;
           
            // Recursive division to find
            // prime factorization of i
            while (t > 1)
            {
                prime_pow.put(SPF[t],
                              prime_pow.get(SPF[t]) - 1);
                t /= SPF[t];
            }
        }
       
        // long because mod is large and a%mod
        // * b%mod can overflow int
        long ans = 1, mod = 1000000007;
       
        // use (a*b)%mod = (a%mod * b%mod)%mod
        for (int i : prime_pow.keySet())
           
            // pow(base,exp,mod) is used to
            // find (base^exp)%mod fast
            ans = (ans * pow(i, prime_pow.get(i), mod))
                  % mod;
        return (int)ans;
    }
   
    // Driver code
    public static void main(String[] args)
    {
        int n = 5, r = 2;
        System.out.print("Value of C(" + n + ", " + r
                         + ") is " + nCr(n, r) + "\n");
    }
}
// This code is contributed by Gautam Wadhwani

Python3

# Python code for the above approach
import math
 
class GFG:
    def nCr(self, n, r):
       
        # Base case
        if r > n: 
            return 0
           
        # C(n,r) = C(n,n-r) Complexity for this
        # code is lesser for lower n-r
        if n - r > r: 
            r = n - r
             
        # List to store smallest prime factor
        # of every number from 1 to n
        SPF = [i for i in range(n+1)]
        for i in range(4, n+1, 2):
           
            # set smallest prime factor of
            # all even numbers as 2
            SPF[i] = 2
     
        for i in range(3, n+1, 2): 
         
            if i*i > n:
                break
               
            # Check if i is prime
            if SPF[i] == i: 
                 
                # All multiples of i are composite
                # (and divisible by i) so add i to
                # their prime factorization getpow(j,i) times
                for j in range(i*i, n+1, i):
                    if SPF[j] == j:
                       
                        # set smallest prime factor
                        # of j to i only if it is
                        # not previously set
                        SPF[j] = i
         
         # dictionary to store power of each prime in C(n,r)
        prime_pow = {} 
         
        # For numerator count frequency
        # of each prime factor
        for i in range(r+1, n+1):
            t = i
             
            # Recursive division to
            # find prime factorization of i
            while t > 1:
                if not SPF[t] in prime_pow:
                    prime_pow[SPF[t]] = 1
                else:
                    prime_pow[SPF[t]] += 1
                t //= SPF[t]
         
        # For denominator subtract the
        # power of each prime factor
        for i in range(1, n-r+1): 
            t = i
             
            # Recursive division to
            # find prime factorization of i
            while t > 1: 
                prime_pow[SPF[t]] -= 1
                t //= SPF[t]
        ans = 1
        mod = 10**9 + 7
         
         # Use (a*b)%mod = (a%mod * b%mod)%mod
        for i in prime_pow:
           
            # pow(base,exp,mod) is used to
            # find (base^exp)%mod fast
            ans = (ans*pow(i, prime_pow[i], mod)) % mod
        return ans
 
 
# Driver code
n = 5
k = 2
ob = GFG()
print("Value of C(" + str(n) +
      ", " + str(k) + ") is",
      ob.nCr(n, k))
 
# This is code is contributed by Gautam Wadhwani
输出
Value of C(5, 2) is 10

时间复杂度: O(n * log(n)),当r-> n / 2时非常有用

辅助空间: O(n)

参见O(log(n))中的素因式分解

另一种方法:(模块化反转技术)

1. nCr的通式为(n *(n-1)*(n-2)*…*(n-r + 1))/(r!)。我们可以直接使用此公式来找到nCr。但这将超出范围。我们需要找到nCr mod m,以使其不会溢出。我们可以使用模块化算术公式轻松地做到这一点。

for the  n*(n-1)*(n-2)* ... *(n-r+1) part we can use the formula,
(a*b) mod m = ((a % m) * (b % m)) % m

2.并为1 / r!部分,我们需要找到从1到r的每个数字的模逆。然后,使用与1到r的模逆相反的上述公式。我们可以使用公式找到O(r)时间的模逆,

inv[1] = 1
inv[i] = − ⌊m/i⌋ * inv[m mod i] mod m
To use this formula, m has to be a prime.

在练习题中,我们需要用模1000000007来表示答案,这是一个质数。

因此,此技术将起作用。

C++

// C++ program for the above approach
#include
using namespace std;
 
// Function to find binomial
// coefficient
int binomialCoeff(int n, int r)
{
 
    if (r > n)
        return 0;
    long long int m = 1000000007;
    long long int inv[r + 1] = { 0 };
    inv[1] = 1;
 
    // Getting the modular inversion
    // for all the numbers
    // from 2 to r with respect to m
    // here m = 1000000007
    for (int i = 2; i <= r; i++) {
        inv[i] = m - (m / i) * inv[m % i] % m;
    }
 
    int ans = 1;
 
    // for 1/(r!) part
    for (int i = 2; i <= r; i++) {
        ans = ((ans % m) * (inv[i] % m)) % m;
    }
 
    // for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for (int i = n; i >= (n - r + 1); i--) {
        ans = ((ans % m) * (i % m)) % m;
    }
    return ans;
}
 
/* Driver code*/
int main()
{
    int n = 5, r = 2;
    cout << "Value of C(" << n << ", " << r << ") is "
         << binomialCoeff(n, r) << endl;
    return 0;
}

Java

// JAVA program for the above approach
import java.util.*;
class GFG
{
 
// Function to find binomial
// coefficient
static int binomialCoeff(int n, int r)
{
 
    if (r > n)
    return 0;
    long  m = 1000000007;
    long  inv[] = new long[r + 1];
    inv[1] = 1;
 
    // Getting the modular inversion
    // for all the numbers
    // from 2 to r with respect to m
    // here m = 1000000007
    for (int i = 2; i <= r; i++) {
        inv[i] = m - (m / i) * inv[(int) (m % i)] % m;
    }
 
    int ans = 1;
 
    // for 1/(r!) part
    for (int i = 2; i <= r; i++) {
        ans = (int) (((ans % m) * (inv[i] % m)) % m);
    }
 
    // for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for (int i = n; i >= (n - r + 1); i--) {
        ans = (int) (((ans % m) * (i % m)) % m);
    }
    return ans;
}
 
/* Driver code*/
public static void main(String[] args)
{
    int n = 5, r = 2;
    System.out.print("Value of C(" +  n+ ", " +  r+ ") is "
         +binomialCoeff(n, r) +"\n");
}
}
 
// This code contributed by Rajput-Ji

Python3

# Python3 program for the above approach
 
# Function to find binomial
# coefficient
def binomialCoeff(n, r):
     
    if (r > n):
        return 0
         
    m = 1000000007
    inv = [0 for i in range(r + 1)]
    inv[1] = 1
 
    # Getting the modular inversion
    # for all the numbers
    # from 2 to r with respect to m
    # here m = 1000000007
    for i in range(2, r + 1):
        inv[i] = m - (m // i) * inv[m % i] % m
 
    ans = 1
 
    # for 1/(r!) part
    for i in range(2, r + 1):
        ans = ((ans % m) * (inv[i] % m)) % m
 
    # for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for i in range(n, n - r, -1):
        ans = ((ans % m) * (i % m)) % m
         
    return ans
 
# Driver code
n = 5
r = 2
 
print("Value of C(" ,n , ", " , r ,
      ") is ",binomialCoeff(n, r))
 
# This code is contributed by rohan07

C#

// C# program for the above approach
using System;
 
public class GFG
{
 
// Function to find binomial
// coefficient
static int binomialCoeff(int n, int r)
{
 
    if (r > n)
    return 0;
    long  m = 1000000007;
    long  []inv = new long[r + 1];
    inv[1] = 1;
 
    // Getting the modular inversion
    // for all the numbers
    // from 2 to r with respect to m
    // here m = 1000000007
    for (int i = 2; i <= r; i++) {
        inv[i] = m - (m / i) * inv[(int) (m % i)] % m;
    }
 
    int ans = 1;
 
    // for 1/(r!) part
    for (int i = 2; i <= r; i++) {
        ans = (int) (((ans % m) * (inv[i] % m)) % m);
    }
 
    // for (n)*(n-1)*(n-2)*...*(n-r+1) part
    for (int i = n; i >= (n - r + 1); i--) {
        ans = (int) (((ans % m) * (i % m)) % m);
    }
    return ans;
}
 
/* Driver code*/
public static void Main(String[] args)
{
    int n = 5, r = 2;
    Console.Write("Value of C(" +  n+ ", " +  r+ ") is "
         +binomialCoeff(n, r) +"\n");
}
}
 
 
 
// This code is contributed by 29AjayKumar
输出
Value of C(5, 2) is 10

时间复杂度: O(n + k)

辅助空间: O(k)

有关时空有效的二项式系数,请参见此

参考:
http://www.csl.mtu.edu/cs4321/www/Lectures/Lecture%2015%20-%20Dynamic%20Programming%20Binomial%20Coefficients.htm

https://cp-algorithms.com/algebra/module-inverse.html