求组合数
typedef long long ll;
//组合数可能比较大,防溢出,使用long long类型
ll C(ll n,ll m){//n个数中选m个数的所有组合
ll res = 1;
for(ll i =1;i<=m;i++){
res = res* (n-m+i)/i; // 注意一定要先乘再除,避免整数除法的结果被截断
}
return res;
}
如何理解?
下面是求组合数的数学公式:
C(n, m) = n! / (m! * (n-m)!)
= (n * (n-1) * ... * (n-m+1)) / (m * (m-1) * ... * 2 * 1)
显然, n! / ( n - m )! = ( n - m + 1 )!
,于是可以将上述式子化简为:(n - ( m - 1 ))! / m!
,展开就是上面最终结果的式子了。
这其中唯一变化的就是m
了,算法不言自明。