题意:
一个人要寄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 ",buf[n]); } return 0; }