http://172.20.6.3/Problem_Show.asp?ID=1544&a=ProbNF
看了题解才意识到原题有错排的性质(开始根本不知道错排是什么)。
十本不同的书放在书架上。现重新摆放,使每本书都不在原来放的位置。有几种摆法?
这个问题的解答就是10个元素的错排数。
错排定义:考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。
错排数的递推式
当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数(错排数)用D(n)表示,
那么D(n) = (n-1) *[D(n-2) + D(n-1)];
还是数学方面的积累太少了
代码
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 using namespace std; 7 const int maxn=210; 8 struct har{ 9 int e[maxn*3],len; 10 har(){memset(e,0,sizeof(e));len=1;} 11 };har f[maxn]; 12 int n; 13 har plu(har x,har y){ 14 har z;z.len=max(x.len,y.len); 15 for(int i=1;i<=z.len;i++){ 16 z.e[i]+=x.e[i]+y.e[i]; 17 z.e[i+1]+=z.e[i]/10; 18 z.e[i]%=10; 19 if(z.e[i+1]>0&&z.len<i+1){ 20 z.len=i+1; 21 } 22 } 23 return z; 24 } 25 har mul(har x,int k){ 26 har z;z.len=x.len; 27 for(int i=1;i<=z.len;i++){ 28 z.e[i]+=x.e[i]*k; 29 z.e[i+1]+=z.e[i]/10; 30 z.e[i]%=10; 31 if(z.e[i+1]>0&&z.len<i+1){ 32 z.len=i+1; 33 } 34 } 35 return z; 36 } 37 void put(har x){ 38 for(int i=x.len;i>=1;i--){ 39 printf("%d",x.e[i]); 40 }cout<<endl; 41 } 42 int main(){ 43 scanf("%d",&n);int x; 44 for(int i=1;i<=n;i++){ 45 for(int j=1;j<=n;j++){ 46 scanf("%d",&x); 47 } 48 } 49 f[2].e[1]=1; 50 f[1].e[1]=0; 51 for(int i=3;i<=n;i++){ 52 f[i]=mul(plu(f[i-1],f[i-2]),i-1); 53 } 54 put(f[n]); 55 return 0; 56 }