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