先前的计算方法是编写一个计算阶乘的函数,在通过公式c(n,m) = n!/m!(n-m)!来计算,而long long函数也最多能储存20的阶乘,因此使用该方法计算组合数的范围太小很容易数据溢出。
今天做hdu2068时在百度看到更加简便的算法,可以有效避免数据溢出的问题。先将组合数公式进行变形:c(n,m) = n! / m!(n-m)! = n(n-1)(n-2)…(n-m+1)! / m! = (n-m+1)/1 + (n-m+2)/2 + …+ (n-m+m)/m = (各项乘积)(n-m+k)/k
C代码:
#include <stdio.h>
long long zhs(int n,int m)
{
long long ans = 1;
for (int i = 1; i <= m; i++)
{
ans = ans * (n - i + 1) / i;
}
return ans;
}