错排问题
ybtoj DP-1-1
题目大意
求n个数的错排种数
输入样例
2
输出样例
1
数据范围
1⩽n⩽201\leqslant n \leqslant 201⩽n⩽20
解题思路
设fif_ifi为i个数的错排种数
考虑第i个数能放在前面i-1个位置的其中一个(i-1种选法,要乘i-1)
放在一个位置后,这个位置的数有两种选择:
1.放在i,那么就是剩下i-2个数错排
2.不放在i,那么这个数改为不能放在i,就是i-1个数错排
则fi=(i−1)×(fi−1+fi−2)f_i = (i - 1) \times (f_{i-1}+f_{i-2})fi=(i−1)×(fi−1+fi−2)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n, a[100];
int main()
{scanf("%lld", &n);a[0] = 1;//初值for (ll i = 2; i <= n; ++i)a[i] = (i - 1) * (a[i - 2] + a[i - 1]);//递推printf("%lld", a[n]);return 0;
}