错排问题Dn = (n - 1) * (Dn-1 + Dn-2)

1.什么是错排问题?

我们知道,n个有序的元素,应当由n!种排列方式,如若一个排列使所有元素都不在原来的位置上,则这个排列就称为错排,也可称为重排。

如:1         2         3

错排有两种:

2 3 1

3 1 2

2.递推关系Dn = (n - 1) * (Dn-1 + Dn-2)

大概推导过程如下:

Dn就表示n个元素错排的方法数

第一步:

考虑第n个元素,把它放在除原位置以外的任意位置k,一共有n-1种选择

第二步:

如果选择放在位置k,则第k个元素需要更改位置,第k个元素整体上有两大类选择:

  • 选择放在第n个位置,则剩下的n-2个元素再错排
  • 选择放在除n除k外的其他任意位置,则相当于n-1个元素错排

综上,Dn = (n - 1) * (Dn-1 + Dn-2)

3.根据递推关系递归求解

3.1题目——年会抽奖

题目描述:

链接:年会抽奖__牛客网
来源:牛客网
 

今年公司年会的奖品特别给力,但获奖的规矩却很奇葩:
1. 首先,所有人员都将一张写有自己名字的字条放入抽奖箱中;
2. 待所有字条加入完毕,每人从箱中取一个字条;
3. 如果抽到的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
现在告诉你参加晚会的人数,请你计算有多少概率会出现无人获奖?

3.2递归解法 

import java.util.Scanner;

/**
 * 年会抽奖——错排问题
 *递推公式——Dn = (n - 1) * (Dn-1 + Dn-2)
 * @author sunny
 * @date 2022/06/03 08:57
 **/
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()){
            int n = scanner.nextInt();
            double res = 0;
//            先计算分母
            double a = calcuA(n);
//            再计算分子
            double b = calcuB(n);
            res = (b/a) * 100;
            System.out.printf("%.2f%%\n",res);
        }
    }
//    计算阶乘求分母
    private static double calcuA(int n){
        double ans = 1;
        while(n != 1){
            ans *= n;
            n --;
        }
        return ans;
    }
//    根据递推公式求分子
    private static double calcuB(int n){
        if(n == 1){
            return 0;
        }
        if(n == 2){
            return 1;
        }
        return (n - 1) * (calcuB(n - 1) + calcuB(n - 2));
    }
}

最后,再记一遍,Dn = (n - 1) * (Dn-1 + Dn-2)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨笨在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值