链接
Y b t O J 递 推 例 题 1 YbtOJ\ 递推例题1 YbtOJ 递推例题1
题目描述
求一个有n个数的排列A,使得A[i]不等于i
样例输入
3
样例输出
2
思路
用 f n f_n fn表示有 n n n个数的错排个数
则很容易得到 f 1 = 0 f_1 = 0 f1=0, f 2 = 1 f_2 = 1 f2=1
第n个数字可以放在前面 n − 1 n-1 n−1个位置
那么第 n n n个数字放在第 k k k位
我们就来考虑一下这个数字的放置情况
1.这个数字放在第n位
则为剩下的 n − 2 n-2 n−2的数字的错排,即 f n − 2 f_{n-2} fn−2
2.这个数字不放在第n位
则为 n − 1 n-1 n−1个数字的错排,即 f n − 1 f_{n-1} fn−1
那么很显然的 f n = ( n − 1 ) ( f n − 1 + f n − 2 ) ( n ≥ 3 ) f_n = (n-1)(f_{n-1} + f_{n-2})(n\geq3) fn=(n−1)(fn−1+fn−2)(n≥3)
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
ll f[5005], n;
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]);
}