题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2049

一开始我的想法就是使用错排公式,先使用全排列从N对中选出M对,然后再使用错排对选出的M对进行错排计算,最后二者相乘。

emmm,代码写得很丑,只是提供一个思路,遇到类似的题目可以多一个思考方向。

D(n) = (n-1) [D(n-2) + D(n-1)]

特殊地,D(1) = 0, D(2) = 1.

详细推导过程百度一下你就知道。

 1 /*使用数学公式的思路比较简单,在N对中选择M对出来,也即是全排列的C(N,M),然后对这M对进行全错排,结果再将二者相乘;*/
 2 #include <iostream>
 3 using namespace std;
 4 int D(int n)         //全错排;
 5 {
 6     if(n==1)
 7         return 0;
 8     if(n==2)
 9         return 1;
10     else return 
11         (n-1)*(D(n-1)+D(n-2));     
12 }
13 int C(int n,int m)   //全排列
14 {
15     if(m==0)
16         return 1;
17     if(n==m)
18         return 1;
19     else return C(n-1,m)+C(n-1,m-1);
20 }
21 int main()
22 {
23     int i,n,m;
24     cin>>i;
25     int N,M;        //N是新人对数,M是找错的新郎数;
26 
27     while(i--)
28     {
29     cin>>N>>M;
30     if(M==1)
31     {
32         cout<<1<<endl;
33         continue;
34     }
35     if(N<M)
36     {
37         cout<<"Wrong Input!"<<endl;
38         continue;
39     }
40     else
41     {
42     m=D(M);
43     n=C(N,M);
44     if(N==M)
45         cout<<m<<endl;
46     else 
47         cout<<m*n<<endl;
48     }
49     } 
50     return 0;
51 }

 

转载于:https://www.cnblogs.com/Guhongying/p/9070102.html