使用动态规划实现错排问题-2023年全国青少年信息素养大赛Python复赛真题精选

 [导读]:超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲,这是超平老师解读Python编程挑战赛真题系列的第15讲。

全国青少年信息素养大赛(原全国青少年电子信息智能创新大赛)是“世界机器人大会青少年机器人设计与信息素养大赛”赛事之一,由中国电子学会主办,包含很多赛项,大赛自2013年举办,已连续成功举办八届,已正式入围“2022-2025学年面向中小学生的全国性竞赛活动名单”。 

大赛旨在激发广大青少年的科学兴趣和想象力,培养钻研探究、创新创造的科学精神和实践能力,促进青少年科技创新活动的广泛开展,发现和培养一批具有科研潜质和创新精神的青少年科技创新后备人才。

大赛主要竞赛类别包括电子科技、智能机器人、软件编程三类,全国青少年Python编程挑战赛就属于其中的软件编程类。

一.赛事说明

2023年(第9届)Python挑战赛赛程分为初赛、复赛和总决赛三个阶段。初赛是资格赛,复赛是地方选拔赛,总决赛是全国各地选拔的精英汇聚在一起进行PK。

本届Python挑战赛是在线上举行,参赛选手登录大赛官网在指定页面完成答题并提交答案。评定成绩的依据是同时考虑得分和用时两个方面,首先是得分高者名次靠前,如果得分一样,则用时少者名次靠前。

2023年全国青少年Python编程挑战赛华北赛区(北京)初中组复赛于2023年7月15日正式举行。一共有6道题,全是编程题,考试时间是90分钟。

今天超平老师分享的是第6题,也是最后一题,错排问题。

二.题目描述

题目背景:

圣诞节快到了,公司为每个员工都准备了礼物,每个礼物都有一个精美的盒子。如果所有的礼物都不小心装错了盒子,求所有礼物都装错盒子共有多少种不同情况。

输入描述:

输入一个正整数n表示公司人数,保证n  ≤  20。

输出描述:

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

样例1:

输入:

2

输出:

1

三.思路分析

这是一个典型的错排问题,那什么是错排问题呢,我们来看两个大家都熟悉的生活场景。

10本不同的书放在书架,现重新摆放,使得每本书都不在原来的位置上,有几种摆法?

图片

1个人给10个同学写信,但他把所有的信都装错了信封,问共有多少种错误的方式?

图片

这些都是生活中的错排问题,推而广之,一个n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的一个排列就称为原排列的一个错排。而研究一个排列的错排个数的问题,就称为错排问题。

错排问题,也叫做伯努利-欧拉错装信封问题,它是数学史上著名的数论问题。最早研究这个问题的是丹尼尔·伯努利。后来欧拉对此产生了兴趣,并独立解决了这个难题,并称其为“组合理论的一个妙题”。因此,历史上也将错排问题叫做“伯努利-欧拉装错信封问题”。

很明显,错位问题涉及到排列组合知识,首先能想到的自然是枚举算法,我们使用函数f(n)来表示n个数的错排总数。

当n = 1时,只有一个数字,不可能出现错排情况,所以f(1) = 0;

当n = 2时,全排列只有两种,分别是12和21,其中后者是错排,所以f(2) = 1;

当n = 3时,全排列有6种,分别是123、132、213、231、312、321,其中231和312是错排,所以f(3) = 2;

当n = 4时,全排列有24种,其中错排有9种,分别是2143、2341、 2413、3142、 3412、3421、 4123、4312、 4321,所以f(4) = 9;

......

枚举算法的编程实现是需要使用循环的,并且还是嵌套循环,嵌套的层数取决于n,n = 3时,使用3层循环,n = 4时,则为4层循环,以此类推。

随着n的增大,循环的次数越来越多,由于n是变化的, 直接使用枚举算法是无法编写代码的。

我们不妨换一个思路,对于n个元素的错排问题,可以将转化为 n - 1个元素的错排问题,它们只是规模大小不同,排列的算法其实是一样的。

因此,我们可以使用递推的思想来推导f(n)和f(n-1)之间的关系。

假定n - 1个元素是错排的,在增加第n个元素时,它是不能放在第n个位置(n的正确位置),那么它放在哪儿呢?

我们可以分两步来进行推导。

第一步,选择n的位置。

前面n - 1个元素任何一个位置都是可以的,假设放在第m位上(1 <= m <= n -1)。很显然,n的可选位置有n - 1种方案。

第二步,选择m的位置。

由于m被挤出来了, 需要考虑m的放置问题,m可以放哪些地方呢,此时又可以分两种情况:

  • 放在n的位置,此时m和n的位置是固定的,错排就转化为除了m和n之外,其它n -2位的错排问题,即f(n - 2);

  • 不放在n的位置,此时m的位置是固定的,错排就转化为除了m之外,其它n - 1位的错排问题,即f(n - 1);

因此,我们可以得出如下公式:

图片

熟悉斐波那契数列的同学,应该对这个推导公式比较熟悉。

实际上,伟大的数学家欧拉早在200多年前就已经给出了这个递推公式,并解决了此题,然后将此题誉为“组合理论的一个妙题”。

有了递推公式,我们很容易就可以想到使用递归算法或者动态规划算法来编程实现。

接下来,我们进入具体的编程实现环节。

四.编程实现

根据上面的思路分析,我们使用两种方式来编写代码:

  • 递归算法

  • 动态规划

1.递归算法

根据前面的思路分析和递归算法的实现方式,需要先定义好递归函数,代码如下:

图片

需要注意这里的两个if语句,这也是递归的出口,由于涉及到n - 1和n - 2,所以n = 1和n = 2时是不能直接使用推导公式的。

然后就可以调用递归函数计算出总的组合情况,代码如下:

图片

递归的好处就是代码简洁,理解起来相对比较容易,缺点就是当递归层数较多时,执行时间太长,考试时有可能出现超时的情况。

2.动态规划

动态规划,英文Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。

对于动态规划,通常可以分成如下5个步骤:

  • 确定dp数组以及下标的含义

  • 确定递推公式

  • dp数组如何初始化

  • 确定遍历顺序

  • 举例推导dp数组

首先dp数组,在本题中,dp是一个一维列表,dp[i]表示i个盒子错排的方案数量。

递推公式在思路分析部分已经确定好了。

然后就是初始化了,我们只需要考虑dp[1]和dp[2]的情况即可。根据前面的分析,dp[1] = 0,dp[2] = 1。

我们先定义一个函数,用于计算错排数量,代码如下:

图片

简单说明两点:

1). 为了方便计算,对于n个盒子,将列表长度设置为n + 1,其中dp[0]可以不用管,或者理解为n为0的情况;

2). 由于dp[1]和dp[2]是不能使用推导公式,所以循环需要在从n = 3开始,直到第n个元素结束,包括第n个元素。

接下来,获取用户输入,调用函数即可,代码如下:

图片

如果我们将dp数组打印出来,可以看到如下结果:

图片

这是n = 20的情况,测试程序,可以发现,随着n的增大,仍然可以在很短的时间内输出结果,这就是动态规划算法的强大之处了。

五.总结与思考

本题难度较大,考查的知识点主要包括:

  • 处理输入数据;

  • 函数的定义及使用;

  • 列表的运算及操作;

  • 递归算法;

  • 动态规划算法;

作为初中组复赛压轴题,本题还是非常有难度的,这里的排列组合已经涉及到高中数学知识了。

虽然我们并不需要使用数学方法来解决,但要想完美的解决这个问题,需要理解并掌握动态规划算法。

给你留一个小小的思考题,除了上面提到的递归算法和动态规划算法,实际上还有两种算法可以解决,一是使用itertools中的permutations函数,二是使用迭代算法,赶紧动手尝试一下吧。

类似的错排问题还有不少,超平老师再给你来两题吧。

教室里有10个座位(1 ~ 10),10位同学分别坐在一个不同的位置上(1 ~ 10),现要求打乱所有同学的位置,打乱规则如下:所有的同学都不能出现在原来的位置上,问有多少种打乱的方法?

家中阳台有10盆不同的花,为保持新鲜感,希望每天重新摆放,使得每盆花都不在第一天放的位置。那么最多可以保持多少天每天摆法都不同?

你还有什么巧妙的解决方案吗,欢迎和超平老师交流。

如果你觉得文章对你有帮助,别忘了点赞和转发,予人玫瑰,手有余香😄

更多教程,请移步至“超平的编程课”gzh。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/82037.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据Flink(五十七):Yarn集群环境(生产推荐)

文章目录 Yarn集群环境(生产推荐) 一、准备工作

Clickhouse 存储引擎

一、常用存储引擎分类 1.1 ReplacingMergeTree 这个引擎是在 MergeTree 的基础上&#xff0c;添加了”处理重复数据”的功能&#xff0c;该引擎和MergeTree的不同之处在于它会删除具有相同主键的重复项。 特点: 1使用ORDERBY排序键作为判断重复的唯一键 2.数据的去重只会在合并…

Openlayers实战:使几何图形适配窗口

Openlayers开发的项目中,有一种应用非常重要,就是绘制或者显示出几何图形后,让几何图形居中并适配到窗口下,这样能让用户很好的聚焦到所要看的内容中去。 这里使用了fit的这个view 的方法,具体的操作请参考示例源代码。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozh…

apple pencil二代值不值得买?好用的苹果平替笔推荐

自从苹果的Pencil系列问世以来&#xff0c;在国内电容笔市场的销量大增&#xff0c;而苹果的Pencil系列&#xff0c;其的售价更是贵的让人望而却步。现在市面上有很多平替的电容笔&#xff0c;都能取代苹果的Pencil&#xff0c;用来做笔记、做批注、写写字都绰绰有余了。在这里…

【状态估计】一维粒子滤波研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

记录线上一次mysql只能查询,不能插入或更新的bug

错误复现 突然有一天产品通知xx服务不可用&#xff0c;想着最近也没有服务更新&#xff0c;就先排查一下服务日志 使用postman测试的时候请求明显超时&#xff0c;查看日志显示是一个锁的问题 使用工具连接到mysql&#xff0c;查看information_schema.INNODB_TRX,发现有一个事…

边写代码边学习之RNN

1. 什么是 RNN 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种以序列数据为输入来进行建模的深度学习模型&#xff0c;它是 NLP 中最常用的模型。其结构如下图&#xff1a; x是输入&#xff0c;h是隐层单元&#xff0c;o为输出&#xff…

Promise详细版

promise基础原理到难点分析 常见的Promise的方法解读 扩展async和await深入分析 逐步分析Promise底层逻辑代码 一、Promise基础 1.什么是promise 为了解决回调地狱&#xff1a; //2.设置点击事件btn.onclick function() {//3.创建ajax实例化对象let xhr new XMLHttpRe…

appium自动爬取数据

爬取类容&#xff1a;推荐知识点中所有的题目 爬取方式&#xff1a;appium模拟操作获取前端数据 入门级简单实现&#xff0c;针对题目和答案是文字内容的没有提取出来 适用场景;数据不多&#xff0c;参数加密&#xff0c;反爬严格等场景 from appium import webdriver impor…

策略模式——算法的封装与切换

1、简介 1.1、概述 在软件开发中&#xff0c;常常会遇到这种情况&#xff0c;实现某一个功能有多条途径。每一条途径对应一种算法&#xff0c;此时可以使用一种设计模式来实现灵活地选择解决途径&#xff0c;也能够方便地增加新的解决途径。为了适应算法灵活性而产生的设计模…

【工程优化问题】基于多种智能优化算法的压力容器设计问题研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【C# 基础精讲】循环语句:for、while、do-while

循环语句是C#编程中用于重复执行一段代码块的关键结构。C#支持for、while和do-while三种常见的循环语句&#xff0c;它们允许根据条件来控制代码块的重复执行。在本文中&#xff0c;我们将详细介绍这三种循环语句的语法和使用方法。 for循环 for循环是一种常见的循环结构&…

进程通信常见方式

目录 通信通信概述 通信的主要方式 进程同步机制--低级进程通信 高级通信工具 共享存储器系统(Shared-Memory System&#xff09; 管道(pipe)通信系统 客户机-服务器系统(Client-Server system)---套接字&#xff08;Socket&#xff09; 客户机-服务器系统(Client-Serv…

微信小程序开发【从0到1~入门篇】2023.08

一个小程序主体部分由三个文件组成&#xff0c;必须放在项目的根目录&#xff0c;如下&#xff1a; 文件必须作用app.js是小程序逻辑app.json是小程序公告配置app.wxss否小程序公告样式表 3. 小程序项目结构 一个小程序页面由四个文件组成&#xff0c;分别是&#xff1a; 文…

JUC并发编程(JUC核心类、TimeUnit类、原子操作类、CASAQS)附带相关面试题

目录 1.JUC并发编程的核心类 2.TimeUnit&#xff08;时间单元&#xff09; 3.原子操作类 4.CAS 、AQS机制 1.JUC并发编程的核心类 虽然java中的多线程有效的提升了程序的效率&#xff0c;但是也引发了一系列可能发生的问题&#xff0c;比如死锁&#xff0c;公平性、资源管理…

Redis—持久化

这里写目录标题 AOF三种写回策略写回策略的优缺点AOF 重写机制AOF后台重写AOF优缺点使用命令 RDBRDB 持久化的工作原理执行快照时&#xff0c;数据能被修改吗RDB 持久化的优点RDB 持久化的缺点 混合持久化大key对持久化的影响 AOF 保存写操作命令到日志的持久化方式&#xff0…

MyBatis核心 - SqlSession如何通过Mapper接口生成Mapper对象

书接上文 MyBatis – 执行流程 我们通过SqlSession获取到了UserMapper对象&#xff0c;代码如下&#xff1a; // 获取SqlSession对象 SqlSession sqlSession sqlSessionFactory.openSession();// 执行查询操作 try {// 获取映射器接口UserMapper userMapper sqlSession.get…

什么CRM客户管理系统好用?公司规模不大,有推荐吗?

CRM客户管理系统是什么&#xff1f; 一句话来概括&#xff1a;CRM是客户关系管理的缩写&#xff0c;指企业通过建立客户档案、跟进客户需求、提供优质服务来维系客户关系的一种管理模式。通常我们认知中的CRM管理系统软件&#xff0c;往往作用于企业的三个流程&#xff1a; 1…

机器学习笔记之优化算法(十)梯度下降法铺垫:总体介绍

机器学习笔记之优化算法——梯度下降法铺垫&#xff1a;总体介绍 引言回顾&#xff1a;线搜索方法线搜索方法的方向 P k \mathcal P_k Pk​线搜索方法的步长 α k \alpha_k αk​ 梯度下降方法整体介绍 引言 从本节开始&#xff0c;将介绍梯度下降法 ( Gradient Descent,GD ) …

学习总结(TAT)

好久都没交总结了&#xff0c;今天把之前的思路和错误整理了一下&#xff1a; 在服务器和客户端两侧&#xff0c;不可以同时先初始化获取输入流&#xff0c;否则会造成堵塞&#xff0c;同时为这位作者大大打call&#xff1a; (3条消息) 关于Java Socket和创建输入输出流的几点…