【题解】错排问题

本文探讨了一个经典的组合数学问题——错位排列问题。通过递推公式 a[i] = (i-1) * (a[i-1] + a[i-2]),解决了n封信和n个信封全部错配的情况下有多少种不同的排列方式。给出了一段C++代码实现该算法,并通过实例解释了递推过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

 

输入输出格式

输入格式

        一行,一个整数n(n≤10)。

 

输出格式

        一行,为所有的情况数。

 

输入输出样例

输入样例

4

 

输出样例

9

 

题解

        现在假设有$i$封信需要处理。

        当第$i$封信放在$[1,i)$中的第$j$个信封时,如果第$j$封信放到了第$i$个信封中,我们其实可以把当前情况下的情况数看做只有$(i-2)$封信的情况数。

        但如果第$j$封信放在了$[1,i)$中的第$k$个信封时,其实我们可以把第$i$个信封看做第$j$个信封,忽略实际已放了第$i$封信的第$j$个信封,这样我们就可以把当前的情况数看做只有$(i-1)$封信的情况数。

        这样就可以得到递推式:$a[i]=(i-1)\times(a[i-1]+a[i-2])$。

#include <iostream>

using namespace std;

int n;
int a[11] = {0,1,1,2};

int main()
{
    cin >> n;
    for(int i = 4; i <= n; i++)
    {
        a[i] = (i - 1) * (a[i - 1] + a[i - 2]); 
    }
    cout << a[n];
    return 0;
}
参考程序

 

转载于:https://www.cnblogs.com/kcn999/p/10661679.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值