问题描述
考虑一个n个数字的排列,使所有的数字都不在自己所对应序号的位置上,这样的一个排列就称为原排列的一个错排,现在给定一个数字n,求解所有可能的错排的个数。
分析
首先使用 表示n个数字的错排数目, 表示n-1个数字的全排列数目,以此类推,推导过程:
- 对于第 个位置的数字 ,首先选取一个位置 (任意的非 的位置)放置,共有 种情况
- 然后考虑第 个位置的数字 ,如果 放在第 个位置,那么相当于剩下的 个数字进行错排,即共有 种情况,( , 都已经确定了位置),如果 不放在第 个位置,那么就相当于 个数字进行错排,也就是 ,(这种情况,只有 的位置确定了)
综上,所有的情况就是:
这就是n个数字进行错排的递推公式,很多题目,例如SDUT2058,都考察到了这一点:
代码:
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
long long int sav[25];
int n;
int main(){
sav[1]=0;
sav[2]=1;
for(int i=3; i<21; i++){
sav[i] = (i-1) * (sav[i-1] + sav[i-2]);
}
while(cin>>n){
cout<<sav[n]<<endl;
}
return 0;
}
以上~