hdu 2068 RPG的错排

题目链接: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\n",sum);
50     }
51     return 0;
52 }
View Code

 

posted @ 2014-03-31 10:55  lysr__tlp  阅读(554)  评论(0编辑  收藏  举报