P1595 信封问题

题目描述

某人写了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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值