想不到刷普及-的题目还真有收获
https://www.luogu.org/problem/show?pid=1595#sub
解:伯努利错装信封问题,公式上!
f(n)=(n-1)*(f(n-1)+f(n-2))
(n表示信封数)
【算法分析】首先,f(0)=1, f(1)=0, f(2)=1
当n>2时,设第一封信装在第二个信封中 (有n-1种方法)
此时若第二封信装在第一个信封中,则剩下的即为n-2错排问题 (f(n-2)种方法)
若第二封信不装在第一个信封中,把第二封信看作与第一个信封为一套
(与错排意思相同),剩下的即为n-1错排问题 (f(n-1)种方法)
得出公式:f(n)=(n-1)*(f(n-1)+f(n-2))(n表示信封数)
就是错排公式啦
#include<bits/stdc++.h>
#define Ll long long
using namespace std;
int f[10000];
int n;
int main()
{
scanf("%d",&n);
f[0]=1;f[1]=0;f[2]=1;
for(int i=3;i<=n;i++)
f[i]=(i-1)*(f[i-1]+f[i-2]);
printf("%d",f[n]);
}