题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2068
错排:http://zh.wikipedia.org/zh-hk/%E9%94%99%E6%8E%92%E9%97%AE%E9%A2%98
D1=0,D2=1。当n≥3时,不妨设n排在了第k位,其中k≠n,也就是1≤k≤n-1。那么我们现在考虑第n位的情况。
- 当k排在第n位时,除了n和k以外还有n-2个数,其错排数为Dn-2。
- 当k不排在第n位时,那么将第n位重新考虑成一个新的“第k位”,这时的包括k在内的剩下n-1个数的每一种错排,都等价于只有n-1个数时的错排(只是其中的第k位会换成第n位)。其错排数为Dn-1。
所以当n排在第k位时共有Dn-2+Dn-1种错排方法,又k有从1到n-1共n-1种取法,我们可以得到:
- Dn=(n-1)(Dn-1+Dn-2)
-
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <math.h> 6 #include <queue> 7 #include <vector> 8 #define ll __int64 9 #define dou double 10 11 using namespace std; 12 13 const ll T=1e2+5; 14 const ll mod=100; 15 16 ll dp[20]={0}; 17 18 void begin( ) 19 { 20 dp[1]=0; 21 dp[2]=1; 22 for(ll i=3;i<20;i++) 23 dp[i]=(i-1)*(dp[i-1]+dp[i-2]); 24 // for(ll i=3;i<20;i++) 25 // printf("%I64d ",dp[i]); 26 27 } 28 29 ll find( ll m,ll n) 30 { 31 ll s=1; 32 for(ll i=n;i>n-m;i--) 33 s*=i; 34 for(ll i=m;i>1;i--) 35 s/=i; 36 return s; 37 } 38 39 40 int main( ) 41 { 42 begin( ); 43 ll n,sum; 44 while( scanf("%I64d",&n),n ) 45 { 46 sum=1; 47 for(ll i=1;i<=n/2;i++) 48 sum+=find( i, n )*dp[i]; 49 printf("%I64d ",sum); 50 } 51 return 0; 52 }