【YbtOJ高效进阶 递推-1】错排问题

链接

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 n1个位置
那么第 n n n个数字放在第 k k k
我们就来考虑一下这个数字的放置情况
1.这个数字放在第n位
则为剩下的 n − 2 n-2 n2的数字的错排,即 f n − 2 f_{n-2} fn2
2.这个数字不放在第n位
则为 n − 1 n-1 n1个数字的错排,即 f n − 1 f_{n-1} fn1
那么很显然的 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=(n1)(fn1+fn2)(n3)

代码

#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]);
}

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/111707438