此法大概可以计算1000以内的组合数,说说原理吧
c(n,m)=c(n,n-m)
可以写成c(n,m)=c(n,min(m,n-m))方便计算 c(n,m)=(n-min(m,n-m)+1)*.....n/min(m,n-m)!
两边取对数 lnc(n,m)=(ln(n-min(m,n-m)+1)+...ln(n))- (ln2+ln3+...ln(m,n-m))
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <algorithm>
using namespace std;
int min(int x,int y)
{
return x>y?y:x;
}
double lnC(int n,int m)
{
if(n<m) return 0;
double s1=0,s2=0;
m=min(m,n-m);
int i;
for(i=n-m+1;i<=n;i++)
s1+=log((double)i);
for(i=2;i<=m;i++)
s2+=log((double)i);
return s1-s2;
}
double C(int n,int m)
{
if(n<m) return 0;
return exp(lnC(n,m));
}
int main()
{
int T,n,m;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
printf("%.0lf\n",C(n,m));
}
return 0;
}