题意:
一个人要寄n个信封,结果装错了。信纸的编号为1到n,信封的编号为1到n,信纸的编号不能和信封的编号一样,全都不能一样。
思路:错排公式。
D(n)表示n件信封装错的所有的情况。
1、将编号为n的信纸装进编号为k的信封,有n-1中装法;
2、再将编号为n-1的信纸装进信封,此时有两种情况:
(1)如果将编号为n-1的信纸装进编号为n的信封,则还剩下n-2张信纸,这n-2张信纸的装法为D(n-2)种;
(2)如果将编号为n-1的信纸装进的不是编号为n的信封,则相当于还有n-1种信纸没装,装法为D(n-1)种;
公式:D(n) = (n-1) * (D(n-1) + D(n-2));
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#define FRE() freopen("in.txt","r",stdin)
using namespace std;
typedef long long ll;
const int maxn = 50;
ll buf[maxn];
inline void init()
{
buf[1] = 0;
buf[2] = 1;
buf[3] = 2;
for(int i = 3; i < maxn; i++)
{
buf[i] = (i-1) * (buf[i-1] + buf[i-2]);
}
}
int main()
{
int n;
init();
while(~scanf("%d",&n))
{
printf("%I64d\n",buf[n]);
}
return 0;
}