最小剩余空间-第11届蓝桥杯省赛Python真题精选

这篇具有很好参考价值的文章主要介绍了最小剩余空间-第11届蓝桥杯省赛Python真题精选。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第31讲。

最小剩余空间,本题是2020年6月20日举办的第11届蓝桥杯青少组Python编程省赛真题,题目要求编程计算空间问题,在n个物品中,任取若干个装入容器内,如何使容器的剩余空间为最小。

先来看看题目的要求吧。

一.题目说明

时间限制:4000Ms

内存限制:589824K3

编程实现

现有一个容器,其容量为V(0 < V < 1001,正整数),同时有n个物品(0< n ≤ 30),每个物品体积大小不同(正整数)。在n个物品中,任取若干个装入容器内,使容器的剩余空间为最小。

输入描述

输入容器大小V(0 < V < 1001,正整数)

输入物品数量n(0 < n ≤ 30)

输入n个物品的不同大小(正整数)

输出描述

剩余最小空间值

样例输入:

100

4

50

20

45

19

样例输出

5

样例输入说明:

"100"输入的是容器大小V,"4"输入的是物品数量n,"50", "20","45","19"输入的是4个物品体积。

样例输出说明

“5”是容器大小100减掉4个物体不同组合最为接近容器大小的一组值。(物品组合个数不限制,只找组合后最接近容器大小的值)

评分标准:

  • 20分:能正确输出一组数据;

  • 20分:能正确输出两组数据;

  • 20分:能正确输出三组数据;

  • 20分:能正确输出四组数据;

  • 20分:能正确输出五组数据。

二.思路分析

这是一道算法题,考查的知识点涉及枚举、组合算法和动态规划算法。

经典的装箱问题,这是信奥一本通书中的一道原题,题号是1295。对于C++而言,解决的方法是动态规划,对于Python而言,除了动态规划,还可以使用组合算法来实现。

首先,我们要彻底理解题目的意思,在n个物品中,任取若干个装入容器内,使容器的剩余空间为最小。容器的容量是固定的,剩余空间最小,就意味着物品的组合要占用最大的空间。

需要注意,每个物品最多只能取1次,要么不取,要么就取,就只有两种不同的状态。

如果将物品的体积当作价值,问题就变成了在固定大小的容器中装入价值最大的物品,这不就是鼎鼎大名的01背包吗?

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

接下来,我们分别使用组合和动态规划两种算法来分析其实现思路。

1.组合算法

组合算法相对比较容易理解,就是找出所有的组合,看看在这些组合中,满足总体积小于V的组合中,哪个的总体积最大。

以题目给出的样例数据进行分析,容器的容量为100,4个物品的体积大小分别为50、20、45和19。

由于物品可以是任意组合的,我们分4种情况来讨论。

1). 只选取一个物品时,有4种组合,如下:

(50)、(20)、(45)、(19);

其中,总体积最大的是50,即只选第一个物品。

2). 选取两个物品时,有6种组合,如下:

(50,20)、(50,45)、(50,19)、(20,45)、(20,19)、(45,19)

其中,总体积最大的是95,即选择1和3两个物品。

3). 选取3个物品时,有4种组合,如下:

(50,20,45)、(50,20,19)、(50,45,19)、(20,45,19)

其中,组合(50, 20, 45)和(50, 45, 19)的总体积超过100,直接忽略,在剩下的两组中,总体积最大的是89,即选择1、2、4这3个物品。

4). 选取4个商品,只有一种组合,如下:

(50,20,45,19);

组合的总体积超过100,可以忽略。

由此,我们可以得出,在不超过100的组合中,选择50和45这两个物品的总容量是最大的,总体积是95,因此剩余空间是100 - 95 = 5。

对于组合的实现,我们可以自己编写代码来实现,但是Python已经提供了内置模块itertools库,可以高效地实现数据的排列组合。

关于itertools库的使用,在《排列组合-第11届蓝桥杯选拔赛Python真题精选》做过详细介绍,这里就不再赘述了。

2. 动态规划算法

动态规划的核心思想是将原问题拆解成若干个重叠的子问题,通过将子问题的解存储起来,避免重复计算,从而提高了算法的效率,其中的核心找到递推公式(状态转移方程)。

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

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

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

  • 确定递推公式

  • 初始化dp数组

  • 确定遍历顺序

对dp数组的确定最为关键,装箱问题需要考虑两个维度,分别是物品和体积,因此需要使用二维数组dp[i][j]来表示,其意思表示在大小为j的容器中,任取0~i中的物品组合时的最大体积

这里的i表示在前i个物品中任意组合,j则表示容器的大小,其取值有讲究,通常是每次增加1。

为了方便说明,我们换一组数据,假定总容量为10,有3个物品,其体积分别是5、8、4,可以制作表格如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

这是一张二维表格,行代表物品,列代表容器的容量,动态规划的过程其实就是如何填写这张表格的过程,填写过程中,始终牢记dp[i][j]的含义。

其中,物品0表示没有装入任何物品,体积0表示容器大小为0,在这两种情况下,结果都为0,所以都初始化为0。

最终,我们要计算出3种物品装入大小为10的容器中的最大体积,这就意味着i = 3,j = 10,对应于dp[3][10],也就是上面表格中最右下角的单元格。

这里的推导公式是什么呢?

此时,我们要使用拆解思维,将大问题拆分成小问题。再次牢记dp[i][j]的含义,它是指前i个物品装入大小为j的容器中的最大值。

不妨反问一下,对于第i个物品,我们到底要不要装入到大小为j的容器中呢,无非就是两种情况:

  • 不装

  • 装入

什么时候不装呢?当然是物品的大小超过当前容器的大小了。

比如将大小为5的物品装入容量为4的容器中,肯定装不下,此时dp[i][j] = dp[i -1][j],dp[i-1][j]的意思是指任意取前i-1个物品组合装入大小为j的容器中的最大体积。

dp[i][j] = dp[i-1][j]

从二维表格的角度来讲,dp[i-1][j]就是dp[i][j]正上方的单元格,这一下好理解了吧?

如果第i个物品的大小小于当前容器的大小,此时就要考虑一下,是装入划算呢,还是不装入划算呢?

如果要装入的话,那么首先就要将自己的体积累加起来,与此同时,它有可能会把其它物品挤出来,这就意味着前i-1个物品在容量只有(j - vi)的最大体积是dp[i-1][j-vi],其中vi是指第i个物品的体积。

是装入划算呢,还是不装入划算呢?

这是个问题,将两种情况拿出来较量一下,取较大的那一个就行,所以,其递推公式如下:

dp[i][j] = max(dp[i-1][j], dp[i-1][j-vi] + vi)

注意,上面的vi应该是vi。

有了递推公式,就可以按照物品从上到下依次遍历,对于每个物品从左到右依次遍历,这是一个嵌套循环。

按照这个思路,可以将上面的表格填充完整,如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

强烈建议你按照上面的分析过程,一步一步地来填写这个表格,表格最右下角的单元格就是最大体积值。

思路有了,接下来,我们就进入具体的编程实现环节。

三.编程实现

根据上面的思路分析,我们使用两种方法来编写程序:

  • 组合算法;

  • 动态规划算法;

1. 组合算法

根据前面的思路分析,编写代码如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

代码不难,简单说明5点:

1). 在输入物品体积的时候,一行一个数据,因此需要使用循环逐个获取并存入列表;

2). combinations()函数有两个参数,第一个参数是可迭代对象,第二个参数是组合的个数,对于n个物品,可以选1个、2个、3个....n个,所以需要使用循环来处理;

3). combinations()函数返回的结果是可迭代对象,为了方便处理,这里使用了list()函数将其转成列表,并追加到res列表中;

4). 在组合过程中,并没有考虑超过v的组合,因此需要单独处理,这里使用了列表推导式,将过滤后的组合进行累加,并存入到列表res1中;

5).  使用max()函数获取最大体积,然后使用v减去最大体积,就是剩余的最小空间了。

2. 动态规划算法

根据思路分析,我们编写代码如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

代码还是挺有难度的,简单说明两点:

1). 根据前面的思路分析,为方便计算,增加了物品0和体积0,因此二维数组的长度需要在给定值的基础上加1;

2). 构造dp数组的时候,使用了列表推导式;

实际上,对于二维数轴的实现,我们可以使用滚动数组的思想进行压缩和简化,然后通过一维数组来实现,其代码如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

关于滚动数组的原理和实现过程,这里就不再展开了,后续超平老师会开辟专题来讲述,代码理解起来有些难度,先参考一下吧。

接下来是测试环节了。

使用题目的样例数据,总容量为100,有4个物品,其体积分别是50、20、45、19,结果如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

假定总容量为10,有3个物品,其体积分别是5、8、4,结果如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

假定总容量为24,有6个物品,其体积分别是8、3、12、7、9、7,结果如下:

最小剩余空间-第11届蓝桥杯省赛Python真题精选,蓝桥杯青少年组Python历年真题,蓝桥杯,python,STEMA测评,少儿编程竞赛

至此,整个程序就全部完成了,你也可以输入不同的数字来测试效果。

四.总结与思考

本题的分数为100分,代码在15行左右,涉及到的知识点包括:

  • 循环语句,主要for...in循环;

  • 输入输出处理;

  • 系统函数的使用;

  • 列表运算;

  • 组合函数;

  • 动态规划算法;

作为高级组最后一题,难度较大,虽然代码不多,这里的难点是动态规划算法的理解和实现。

从题目本身的角度来讲,这是一个组合问题,通常可以使用枚举来实现,但是题目给出的v和n都是变化,使用枚举比较麻烦,而且枚举的效率不高,尤其是对于数据量较大的情况,考试时存在超时情况。

针对排列组合,在Python编程中,最简单的实现方式就是使用itertools库,重点是combinations()和permutations()两个函数。

在一般情况下,combinations函数的效率是很高的,因为它使用了高效的算法来生成组合,并且在实现上进行了优化。

然而,当元素数量较大或者要生成的组合数量非常庞大时,其效率会受到影响。这是因为生成所有可能的组合需要消耗大量的计算资源和内存空间。

在实际使用中,如果需要生成大量组合,可以考虑对算法进行优化,或者使用其他更高效的方法来处理。

作为经典算法,动态规划还是有些难度的,在学习的时候,一定要彻底理解dp数组的含义,结合二维表格来理解,最好的方法就是自己绘制二维表格,一步一步地填写好表格,关于动态规划,超平老师后面会有专题介绍,请持续关注。

超平老师给你留一道思考题,将二维数组简化为一维数组,其原理是什么,需要注意什么问题?

你还有什么好的想法和创意吗,也非常欢迎和超平老师分享探讨。

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

有需要源代码的,可以移步至“超平的编程课”gzh。文章来源地址https://www.toymoban.com/news/detail-798435.html

到了这里,关于最小剩余空间-第11届蓝桥杯省赛Python真题精选的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第十三届蓝桥杯省赛 python B组复盘

    😎🥳😎 备战蓝桥杯第一弹–复盘 思路 (当时第一次参加蓝桥杯,当时现场心里小鹿乱撞,用排序输出了还每个字母数数验证一番(滑稽)) 字符串转列表 列表排序 列表转字符串 代码 思路 当时在现场程序没跑出来 想着那个数取余2余1,取余4余1,取余8余1可以只看取余8余1的,

    2023年04月20日
    浏览(42)
  • 【蓝桥杯冲刺】蓝桥杯11届省赛C++b组真题-编程题

    目录 试题F:成绩统计 解题思路: 代码: 试题G:回文日期 解题思路: 代码: 试题H:字串分值 解题思路: 代码:  试题I:平面切分 解题思路: 代码: 试题J:字串排序 解题思路: 写在最后: 【问题描述】 小蓝给学生们组织了一场考试,卷面总分为 100 分, 每个学生的

    2024年02月02日
    浏览(40)
  • 【蓝桥杯冲刺】蓝桥杯11届省赛C++b组真题-填空题

    目录 试题A:门牌制作 解题思路: 答案: 试题B:既约分数 解题思路: 答案: 试题C:蛇形填数 解题思路: 答案: 试题D:跑步训练 解题思路: 答案: 试题E:七段码 解题思路: 答案: 写在最后: 小蓝要为一条街的住户制作门牌号。 这条街一共有 2020 位住户,门牌号从

    2023年04月19日
    浏览(60)
  • 第十四届蓝桥杯省赛 Python B 组 D 题——管道(AC)

    有一根长度为 len text{len} len 的横向的管道,该管道按照单位长度分为 len text{len} len 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。 一开始管道是空的,位于 L i L_i L i ​ 的阀门会在 S i S_i S i ​ 时刻打开,并不断让水流入管道。 对于位于 L i L_i L i ​ 的阀

    2024年02月07日
    浏览(38)
  • 试题G:全排列的价值(第十三届蓝桥杯省赛Python B组)

      首先,我们先重新排列一下题目所给的例子 我们将每种排列的每个元素价值单独拿出来看看(矩阵1) 不难发现

    2023年04月15日
    浏览(39)
  • 2022蓝桥杯省赛——砍竹子

    问题描述 这天, 小明在砍竹子, 他面前有 n 棵竹子排成一排,一开始第 i 棵竹子的 高度为 hi​。 他觉得一棵一棵砍太慢了, 决定使用魔法来砍竹子。魔法可以对连续的一 段相同高度的竹子使用, 假设这一段竹子的高度为 H, 那么用一次魔法可以把这一段竹子的高度都

    2023年04月09日
    浏览(39)
  • 十四届蓝桥杯省赛CB

    写的时候没跑出来,仅仅是因为给 (i*i) 加了括号,爆了int!!! 双精度浮点的表示范围:-1.79E+308 ~ +1.79E+308 基本类型:int 二进制位数:32(4字节) 最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方) 最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1 double范围很大,基本不可能爆,不

    2024年02月08日
    浏览(42)
  • 2019蓝桥杯省赛题目——“数的分解”

    目录 题目 要求 思路 最后的代码 结果 把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和 1001+1000+18 被视为同一种。 这是一道结果填空

    2024年02月14日
    浏览(40)
  • 蓝桥杯省赛无忧 STL 课件13 list

    以下是一个示例,展示如何使用listt容器: 在上述示例中,我们首先创建了一个list容器myList,然 后使用push_back()和push_front()函数分别在链表尾部和头 部插入元素。最后,使用范围基于范围的for循环遍历链 表并输出元素。 需要注意的是,由于list是双向链表,因此插入和删除操

    2024年02月02日
    浏览(36)
  • 第九届蓝桥杯省赛——3字母阵列(二维数组)

    仔细寻找,会发现:在下面的8x8的方阵中,隐藏着字母序列:“LANQIAO”。 SLANQIAO ZOEXCCGB MOAYWKHI BCCIPLJQ SLANQIAO RSFWFNYA XIFZVWAL COAIQNAL 我们约定: 序列可以水平,垂直,或者是斜向; 并且走向不限(实际上就是有一共8种方向)。 上图中一共有4个满足要求的串。 下面有一个更大的

    2024年02月15日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包