簡要解析:
基本形式: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]);
}