您的位置:首页 > 其它

P1595 信封问题

2018-01-10 11:02 211 查看

题目描述

某人写了n封信和n个信封,如果所有的信都装错了信封。求所有信都装错信封共有多少种不同情况。

输入输出格式

输入格式:

一个信封数n(n<=20)

输出格式:

一个整数,代表有多少种情况。

输入输出样例

输入样例#1:
2


输出样例#1:
1


输入样例#2:
3


输出样例#2:
2


裸数学题,推出递推公式就结束了,long long都不用,用搜索(或者手算)算出前三项就没了

推导过程:

原文链接

全错位排列:即被著名数学家欧拉(Leonhard Euler,1707-1783)称为组合数论的一个妙题的“装错信封问题”。
> 大意如下:
一个人写了n封不同的信及相应的n个不同的信封,他把这n封信都装错了信封,问都装错信封的装法有多少种?
分析:
假设有信封A,B,C,D...;信件1,2,3,4...;全部装错有f(n)种情况。
这里分两种情况考虑:①前面n-1个信封全部装错;②前面n-1个信封有一个没有装错其余全部装错。
①前面n-1个信封全部装错:因为前面n-1个已经全部装错了,所以第n封只需要与前面任一一个位置交换即可,总共有f(n-1)*(n-1)种情况。
②前面n-1个信封有一个没有装错其余全部装错:为什么考虑这种情况,因为n-1个信封中如果有一个没装错,那么我们把那个没装错的与n交换,即可得到一个全错位排列情况。
得到这种情况的种数也很简单,即是忽略掉那个没装错的情况去排列其他的信封的全错排种数f(n-2)*(n-1)。


#include <iostream>
using namespace std;
int dfs(int n)
{
if(n==0)
return 0;
if(n==1)
return 0;
if(n==2)
return 1;
return (n-1)*(dfs(n-1)+dfs(n-2));
}
int main()
{
int n;
cin>>n;
cout<<dfs(n);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: