以下是二项式系数的常见定义。
A binomial coefficient C(n, k) can be defined as the coefficient of x^k in the expansion of (1 + x)^n.
A binomial coefficient C(n, k) also gives the number of ways, disregarding order, that k objects can be chosen from among n objects more formally, the number of k-element subsets (or k-combinations) of a n-element set.
问题
编写一个函数,该函数接受两个参数n和k并返回二项式系数C(n,k)的值。例如,你的函数应该返回6对于n = 4且k = 2,并且应当对于n = 5且k = 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值,将存在许多常见的子问题。
由于再次调用了相同的子问题,因此此问题具有“重叠子问题”属性。因此,二项式系数问题具有动态规划问题的两个属性(请参阅此内容)。像其他典型的动态编程(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