1.排列组合公式
若按照阶乘的方式来计算,在数值较大时可能发生溢出。
观察可以发生C(n,r)的分子分母都为r项,可以把它们的每一项分别进行计算。在编程时要注意除不进时,不要除,把分子分母分别乘到下一个处理项中。
同时 C(n,r)=C(n,n-r)
例:每行输入两个数分别代表上面的n,r。若n,r=0则终止。
/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
int n,r;
// int count=1;
int i;
int a=1,b=1;
while(scanf("%d%d",&n,&r)&&n)
{
if(r>n-r)//减小计算的项
r=n-r;
for(i=1;i<=r;i++)
{
a*=n-i+1;
b*=i;
if(a%b==0)
{
a/=b;
b=1;
}
}
printf("%d\n",a/b);
a=1,b=1;
}
}
2
2.二项式系数公式,即降阶公式
C(n,r)=C(n-1,r)+C(n-1,r-1).可以理解先从n个中选r-1个,然后在n-1个中选r-1个,其中一个就是被排除在n-1中的一个。
所以C(i,j)=C(i-1,j)+C(i-1,j-1)
而C(x,0)=1,所以C(1,1)=C(1,0)=1;
C(2,1)=C(1,1)+C(1,0)=1+1=2;
C(3,1)=C(2,1)+C(2,0)=2+1=3;
C(3,2)=C(2,2)+C(2,1)=1+2=3;
.......
若用数组来存储这些组合的计算,C[i][j]=C[i-1][j]+C[i-1][j-1];
初始时设C[i][0]=1,(0<=i<=101)
然后双重枚举i,j,按上面公式计算。
/* Note:Your choice is C IDE */
#include "stdio.h"
#define N 110
unsigned int C[N][N];//用于存数各排序组合数
void prepare()
{
int i,j;
memset(C,0,sizeof(C));
for(i=0;i<N;i++)
{
C[i][0]=1;
C[i][i]=1;
}
for(i=1;i<N;i++)
{
for(j=0;j<i;j++)
{
C[i][j]=C[i-1][j]+C[i-1][j-1];
}
}
}
void main()
{
int n,m;
prepare();//先离线计算各式
while(scanf("%d%d",&n,&m)&&n)
printf("%d\n",C[n][m]);
}
![](https://img-blog.csdn.net/20140622175753781?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluMjAwNzUz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
转载请标明出处:http://blog.csdn.net/lin200753/article/details/33329613