一、求解问题
计算 C n m = n ! m ! × ( n − m ) ! C^m_n=\dfrac{n!}{m!\times (n-m)!} Cnm=m!×(n−m)!n!,其中m≤n
二、求解思路
1.莽夫思路
我直接算,写一个阶乘的函数,写一个算组合数的函数
long long factorial(int n) {
long long m = 1;
for (int i = 1; i <= n; i++){
m *= i;
}
return m;
}
long long C(int n, int m) {
return factorial(n) / (factorial(m) * factorial(n - m));
}
看似没有问题,但求解 C 25 12 = 5200300 C^{12}_{25}=5200300 C2512=5200300,就出问题, 25 ! 25! 25!溢出了。
2.数学化简
数学公式:
-
C n m = C n n − m C^m_n=C^{n-m}_{n} Cnm=Cnn−m,其中m≤n
-
n ! m ! = ( m + 1 ) ( m + 2 ) … ( n − 1 ) n \dfrac{n!}{m!}=(m+1)(m+2)\dots(n-1)n m!n!=(m+1)(m+2)…(n−1)n,其中m≤n
综上:
如果m<n-m,那么可以让
C
n
m
=
C
n
n
−
m
C^m_n=C^{n-m}_{n}
Cnm=Cnn−m,这样可以让
n
!
m
!
\dfrac{n!}{m!}
m!n!约去最多的部分。
long long C(int n, int m) {
if(m < n-m) {
m = n-m;
}
long long ans = 1;
for(int i = m+1; i <= n; i++) {
ans *= i;
}
for(int i = 1; i <= n-m; i++) {
ans /= i;
}
return ans;
}