Calculer le coefficient binomial en C++ et Python
En combinatoire, le coefficient binomial est utilisé pour désigner le nombre de façons possibles de choisir un sous-ensemble d'objets d'une taille k dans un ensemble plus grand de taille n avec \( k\le n\).
Le coefficient binomial est noté \(\binom{n}{k}\) $$\binom{n}{k} = \frac{n!}{k!(n-k)!}$$
Le coefficient binomial indique le nombre de combinaisons possibles de k objets à partir de n.
Exemple
Le nombre de façons possibles de choisir 2 objets parmi un ensemble de 5 objets est égal à $$\binom{5}{2} = \frac{5!}{2!(3)!} = \frac{5\times4\times3\times2\times1}{(2\times1)\times(3\times2\times1)}=5\times2=10$$
Lorsque nous traitons des combinaisons, nous devons garder à l'esprit que :
- L'ordre dans lequel les k objets sont sélectionnés n'a pas d'importance ;
- Chaque objet ne peut être sélectionné qu'une seule fois.
Écrivez un programme qui prend deux valeurs n et k et renvoie la valeur du coefficient binomial \(\binom{n}{k}\).
Entrée
Une ligne contient deux valeurs n et k
Sortie
La valeur du coefficient binomial \(\binom{n}{k}\)
Exemples
| Entrée du programme | Sortie du programme |
|---|---|
| 5 2 | 10 |
| 100 5 | 75287520 |
| 70 3 | 54740 |
Solution 1 : récursive
Une importante relation, la formule de Pascal, lie les coefficients binomiaux : pour tout couple (n,k) d'entiers naturels : $$\binom{n+1}{k+1} = \binom{n}{k+1} + \binom{n}{k}$$ avec \(\binom{n}{0}=1\) et \(\binom{n}{n}=1\)
Voici une implémentation récursive simple qui suit simplement la structure récursive mentionnée ci-dessus.
#include <iostream>
using namespace std;
int coefBinomial(int n, int k){
if (k > n)
return 0;
if (k == 0 || k == n)
return 1;
return coefBinomial(n-1, k-1) + coefBinomial(n-1, k);
}
int main()
{
int n, k;
cin >> n >> k;
cout << coefBinomial(n,k);
return 0;
}
import sys
def coefBinomial(n, k):
if k > n:
return 0
if k == 0 or k == n:
return 1
return coefBinomial(n-1, k-1) + coefBinomial(n-1, k)
n,k = map(int, sys.stdin.readline().strip().split())
print(coefBinomial(n,k))
Complexité :
- Complexité temporelle : O(n*max(k,n-k))
- Complexité spatiale : O(n*max(k,n-k))
Solution 2 : Programmation dynamique
Il convient de noter que la fonction ci-dessus calcule encore et encore les mêmes sous-problèmes. Voir l'arbre de récurrence suivant pour n = 5 et k = 2. La fonction C(3, 1) est appelée deux fois. Pour de grandes valeurs de n, il y aura de nombreux sous-problèmes communs.

Étant donné que les mêmes sous-problèmes sont appelés à nouveau, ce problème a la propriété chevauchement de sous-problème, de sorte que le problème peut être résolu à l'aide de la programmation dynamique.
#include <iostream>
using namespace std;
int coefBinomial(int n, int k){
int C[n + 1][k + 1];
int i, j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= min(i, k); j++) {
// cas de base
if (j == 0 || j == i)
C[i][j] = 1;
else
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
}
return C[n][k];
}
int main()
{
int n, k;
cin >> n >> k;
cout << coefBinomial(n,k);
return 0;
}
import sys
def coefBinomial(n, k):
C = [[0 for x in range(k+1)] for x in range(n+1)]
for i in range(n+1):
for j in range(min(i, k)+1):
# cas de base
if j == 0 or j == i:
C[i][j] = 1
else:
C[i][j] = C[i-1][j-1] + C[i-1][j]
return C[n][k]
n,k = map(int, sys.stdin.readline().strip().split())
print(coefBinomial(n,k))
Complexité :
- Complexité temporelle : O(n*k)
- Complexité spatiale : O(n*k)
Solution 3 : Meilleure solution
Nous pouvons calculer le coefficient binomial en temps linéaire si nous observons ce qui suit : $$\binom{n}{k} = \frac{n!}{k!(n-k)!}=\frac{n\times(n-1)\times(n-2)\times\dots\times(n-k+1)}{k!}$$
Il faut noter que \(\binom{n}{k}=\binom{n}{n-k}\)
#include <iostream>
using namespace std;
int coefBinomial(int n, int k){
if(k>(n-k))
k=n-k;
int coef=1;
/*
Calculer la valeur de [n * (n-1) *---* (n-k + 1)]
/ [k * (k-1) *----* 1]
*/
for(int i=0;i<k;i++){
coef *= (n-i);
coef /= (i+1);
}
return coef;
}
int main()
{
int n, k;
cin >> n >> k;
cout << coefBinomial(n,k);
return 0;
}
import sys
def coefBinomial(n, k):
if(k>(n-k)):
k=n-k
coef=1
# Calculer la valeur de [n * (n-1) *---* (n-k + 1)]
# / [k * (k-1) *----* 1]
for i in range(k):
coef=coef*(n-i)
coef=coef//(i+1)
return coef
n,k = map(int, sys.stdin.readline().strip().split())
print(coefBinomial(n,k))
Complexité :
- Complexité temporelle : O(min(k,n-k))
- Complexité spatiale : O(1)
