题目
求多少个 n n n 个数的排列 A A A,满足对于任意的 i ( 1 < = i < = n ) A i ≠ i i (1<=i<=n) Ai \neq i i(1<=i<=n)Ai=i 。
其中 1 < = n < = 20 1<=n<=20 1<=n<=20
输入
一个数,n。
输出
一个整数,表示答案。
解
设 f [ n ] f[n] f[n] 为表示 n n n 个数的合法排列个数。
考虑新增第 n n n 位,这个位置肯定不能排 n n n ,所以这个位置有 ( n − 1 ) (n-1) (n−1) 种可能。
假设这个调换到第 n n n 位的数为 k k k。
则,对于数字 n n n,有
1.放到第 k k k 位,剩下 ( n − 2 ) (n-2) (n−2) 种数错排。
2.不放的第 k k k 位,剩下 ( n − 1 ) (n-1) (n−1) 种数字错排。
于是便得到了递推式:
f [ n ] = ( n − 1 ) ( f [ n − 1 ] + f [ n − 2 ] ) ( n > = 3 ) f[n] = (n-1)(f[n-1]+f[n-2])(n>=3) f[n]=(n−1)(f[n−1]+f[n−2])(n>=3)
代码
#include<cstdio>
long long n, f[25];
int main(){
scanf("%lld", &n);
f[1] = 0; f[2] = 1;
for(int i = 3; i <= n; ++i)
f[i] = (i-1) * (f[i-1] + f[i-2]);
printf("%lld", f[n]);
}