递推题目系列之二认错人
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎",具体的操作是这样的: 首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排; 然后,让各位新郎寻找自己的新娘.每人只准找一个,并且不允许多人找一个. 最后,揭开盖头,如果找错了对象就要当众跪搓衣板... 假设一共有N对新婚夫妇,其中有M个新郎找错了新娘,求发生这种情况一共有多少种可能.
Input:
输入数据的第一行是一个整数C,表示测试实例的个数,然后是C行数据,每行包含两个整数N和M(1<M<=N<=20)。
Output:
对于每个测试实例,请输出一共有多少种发生这种情况的可能,每个实例的输出占一行。
Sample Input:
3 3 2 5 3 6 2
Sample Output:
3 20 15
思路:就是m的错排*(n-m)的组合;
错排公式:
D(n) = (n-1) [D(n-2) + D(n-1)]
特殊地,D(1) = 0, D(2) = 1.
AC代码:
1 #include<stdio.h> 2 long long int D(long long int m) 3 { 4 if(m==1) 5 return 0; 6 else if(m==2) 7 return 1; 8 else if(m>2) 9 return (m-1)*(D(m-1)+D(m-2)); 10 } 11 long long fac(int k) 12 { 13 long long f=1; 14 int i; 15 for(i=1;i<=k;i++) 16 f=f*i; 17 return f; 18 } 19 long long int comb(long long int n,long long int m) 20 { 21 long long int c; 22 c=fac(n)/(fac(n-m)*fac(m)); 23 return c; 24 } 25 long long int bfcp(long long int n,long long int m) 26 { 27 long long int k; 28 k=D(m)*comb(n,n-m); 29 return k; 30 } 31 int main() 32 { 33 long long int m,n,c; 34 scanf("%lld",&c); 35 while(c--) 36 { 37 scanf("%lld%lld",&n,&m); 38 printf("%lld\n",bfcp(n,m)); 39 } 40 return 0; 41 }