组合数的常用公式
零、纯暴力法
根据第一个公式,将的分子和分母求出,再相除即可。
适用范围:n,m较小的情况下。
时间复杂度:
第一种部分代码如下:
for(int i = n; i >= n - m + 1; i--)
ans *= i;
for(int i = m; i >= 1; i--)
ans /= i;
第二种部分代码如下:
fz = 1, fm = 1; // fz表示分子,fm表示分母
for(int i = n, j = 1; j <= m; i--, j++){
fz *= i;
fm *= j;
}
ans = fz / fm;
一、杨辉三角法
上面的第三个公式是符合杨辉三角的公式,因此可以使用第三个公式进行预处理题目范围内所有的,需要时直接使用即可。
适用范围:n,m大小在左右。
时间复杂度:
C++部分代码如下:
// c[n][m]表示从n个元素中取m个的方案数
for(int i= 0; i <= N; i++)
for(int j = 0; j <= i; j++)
if(!j) c[i][j] = 1;
else c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
二、预处理法
先预处理出范围内所有数的阶乘和阶乘逆元,根据第一个公式直接取需要的阶乘和阶乘逆元的值即可。
适用范围:n,m在以内,且取模的数mod为素数时。
时间复杂度:
乘法逆元的求法可以参照本人之前的博客: