有个网名叫做8006的男性同学,结交网友无数,最近该同学玩起了浪漫,同时给n个网友每人写了一封信,这都没什么,要命的是,他竟然把所有的信都装错了信封!注意了,是全部装错哟!
现在的问题是:请帮可怜的8006同学计算一下,一共有多少种可能的错误方式呢?
Input
输入数据包含多个多个测试实例,每个测试实例占用一行,每行包含一个正整数n(1<n<=20),n表示8006的网友的人数。
Output
对于每行输入请输出可能的错误方式的数量,每个实例的输出占用一行。
Sample Input
2
3
Sample Output
1
现在的问题是:请帮可怜的8006同学计算一下,一共有多少种可能的错误方式呢?
Input
输入数据包含多个多个测试实例,每个测试实例占用一行,每行包含一个正整数n(1<n<=20),n表示8006的网友的人数。
Output
对于每行输入请输出可能的错误方式的数量,每个实例的输出占用一行。
Sample Input
2
3
Sample Output
1
2
装信封问题是典型的错排问题
错排公式:
f(n)=(n-1)(f(n-1)+f(n-2))
经典的信封问题:
一个人写了
9
封不同的信及相应的
9
个不同的信封,他把
这
n
封信都装错了信封,问都装错信封的装法有多少种?
解题思路:
用
A
、
B
、
C
……
表示写着
n
位友人名字的信封,
a
、
b
、
c
……
表示
n
份相应的写
好的信纸。把错装的总数为记作
f(n)
。假设把
a
错装进
B
里了,包含着这个错误
的一切错装法分两类:
(
1
)
b
装入
A
里,这时每种错装的其余部分都与
A
、
B
、
a
、
b
无关,应有
f(n-2)
种错装法
。
(
2
)
b
装入
A
、
B
之外的一个信封,这时的装信工作实际是把(除
a
之外的)
份
信纸
b
、
c
……
装入(除
B
以外的)
n
-
1
个信封
A
、
C
……
,显然这时装错的方法
有
f(n-1)
种。
总之在
a
装入
B
的错误之下,共有错装法
f(n-2)+f(n-1)
种。
a
装入
C
,装入
D……
的
n
-
2
种错误之下,同样都有
f(n-2)+f(n-1)
种错装法,因此
:
f(n)=(n-1)
(
f(n-1)+f(n-2)
)
#include <stdio.h>
int main()
{
int n,i;
__int64 a[21];
a[1]=0;
a[2]=1;
for(i=3;i<21;i++)
a[i]=(i-1)*(a[i-1]+a[i-2]);
while( scanf("%d",&n) != EOF)
printf("%I64d\n",a[n]);
return 0;
}