hd2068错排+组合

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 __int64 a[20], c[30][30];
 5 
 6 void cc()       //打表 n个数中任意选m个数
 7 {
 8     int i, j;
 9     for(i=0; i<=30; i++)
10         for(j=0; j<=i; j++)
11             if( i==j || j==0 )
12                 c[i][j]=1;
13             else 
14                 c[i][j]=c[i-1][j]+c[i-1][j-1];  //假设第j个数是选中了,那么只要c[i-1][j-1];假设第j个数没被选中,那么只要c[i-1][j]
15 }
16 void aa()        //打表 n个数的错排
17 {
18     int i;
19     a[1]=0;    //注意一个数无法错排(被坑了好久)
20     a[2]=1;
21     for(i=3; i<=20; i++)
22         a[i]=(i-1)*(a[i-1]+a[i-2]); //1.前n-1个数是错排好的,a[i-1]的每一种情况中前i-1个依次与n交换(i-1)*a[i-1] 2.一共有i-1种情况前i-2个数是错排好的(i-1)*a[i-2]
23 }
24 int main()
25 {
26     int n;
27     cc();
28     aa();
29     //cout<<c[3][2]<<endl;
30     while(cin>>n , n)
31     {
32         __int64 sum=1;
33         if(n==1||n==2)cout<<"1"<<endl;
34         else 
35         {
36             for(int i=(n+1)/2; i<n; i++)
37             {
38                 sum+=c[n][i]*a[n-i];
39             }
40             cout<< sum <<endl;
41         }        
42     }
43     return 0;
44 }

链接http://acm.hdu.edu.cn/showproblem.php?pid=2068

posted @ 2015-10-30 20:37  海无泪  阅读(132)  评论(0编辑  收藏  举报