简要解析:
基本形式:d[1]=0; d[2]=1 假设F(N-1)和F(N-2)已经得到
则有以下情况:
当有N封信的时候,前面N-1封信可以有:
①N-1。
②N-2封错装。
分析①:对于每一种错装,可以从N-1封信中任意取一封和第 N封错装,故=F(N-1) * (N-1)。
分析②:只能是没装错的那封信和第N封信交换信封,没装错的那封信可以是前面N-1封信中的任意一个,故= F(N-2) * (N-1)。
递归式:d[n]= (n-1)*( d[n-1] + d[n-2])
后来才知道这就是大名鼎鼎的错排公式。
AC代码如下:
#include<stdio.h>
int main() {
long long arr[21];
int num,i;
arr[1]=0;
arr[2]=1;
// 递推过程 (打表)
for(i=3;i<21;i++)
arr[i]=(i-1)*(arr[i-1]+arr[i-2]);
while(scanf("%d",&num)!=EOF)
printf("%lld\n",arr[num]);
}