当前位置: 首页 > news >正文

华为OD机试_2025 B卷_书籍叠放(Python,200分)(附详细解题思路)

题目描述

书籍的长、宽都是整数对应 (l,w)。如果书A的长宽度都比B长宽大时,则允许将B排列放在A上面。现在有一组规格的书籍,书籍叠放时要求书籍不能做旋转,请计算最多能有多少个规格书籍能叠放在一起。

输入描述
输入:books = [[20,16],[15,11],[10,10],[9,10]]

说明:总共4本书籍,第一本长度为20宽度为16;第二本书长度为15宽度为11,依次类推,最后一本书长度为9宽度为10.

输出描述
输出:3

说明: 最多3个规格的书籍可以叠放到一起, 从下到上依次为: [20,16],[15,11],[10,10]

用例

输入[[20,16],[15,11],[10,10],[9,10]]
输出3

书籍叠放问题:最长严格递减子序列应用

核心解题思路

问题分析

题目要求找出能叠放在一起的最大书籍数量,规则是:

  1. 只有当书籍A的长宽都严格大于书籍B时,才能将B放在A上面
  2. 书籍不能旋转
  3. 需要找到一个书籍序列,使得序列中每个书籍的长宽都严格大于其后面的书籍

解决方案:排序+最长严格递减子序列

  1. 关键洞察:问题本质是寻找二维空间中的最长链,其中每个元素都严格大于链中下一个元素
  2. 排序预处理
  • 按长度降序排序(从大到小)
  • 长度相同时,按宽度降序排序(从大到小)
  1. 问题转化:排序后问题简化为在宽度序列中寻找最长严格递减子序列
  2. 高效算法:使用二分查找维护最小末尾序列,时间复杂度O(n log n)

完整代码实现

import bisectdef max_books(books):"""计算最多能叠放的书籍数量参数:books: 二维列表,每个元素为[长, 宽]返回:最多能叠放的书籍数量"""# 处理空输入if not books:return 0# 1. 对书籍进行排序:长度降序,长度相同则宽度降序books.sort(key=lambda x: (-x[0], -x[1]))# 2. 提取所有书籍的宽度widths = [book[1] for book in books]# 3. 寻找宽度序列的最长严格递减子序列tail = []  # 存储每种长度递减子序列的最小末尾值for w in widths:# 如果当前宽度小于tail的最后一个元素,直接添加if not tail or w < tail[-1]:tail.append(w)else:# 二分查找第一个大于等于w的位置idx = bisect.bisect_left(tail, w)# 用w替换该位置的元素tail[idx] = wreturn len(tail)# 主程序
if __name__ == "__main__":# 读取输入import sysdata = sys.stdin.read().strip()# 处理输入格式:"[[20,16],[15,11],[10,10],[9,10]]"if not data:print(0)else:# 删除两端的方括号data = data[2:-2]# 分割书籍数据book_strs = data.split('],[') if data else []books = []for s in book_strs:# 分割长宽parts = s.split(',')if len(parts) == 2:l = int(parts[0])w = int(parts[1])books.append([l, w])# 计算并输出结果result = max_books(books)print(result)

示例解析

示例1:输入[[20,16],[15,11],[10,10],[9,10]]

  1. 排序处理
  • 原始书籍:[20,16], [15,11], [10,10], [9,10]
  • 按长度降序:[20,16], [15,11], [10,10], [9,10](已有序)
  • 宽度序列:[16, 11, 10, 10]
  1. 构建tail序列
处理16: tail = [16]
处理11: 11<16 → tail = [16,11]
处理10: 10<11 → tail = [16,11,10]
处理10: 10>=10 → 替换第一个>=10的位置(tail[2]) → tail = [16,11,10]
  1. 结果:tail长度=3

示例2:输入[[10,20],[15,15],[16,10],[17,9]]

  1. 排序处理
  • 按长度降序:[17,9], [16,10], [15,15], [10,20]
  • 宽度序列:[9,10,15,20]
  1. 构建tail序列
处理9: tail = [9]
处理10: 10>=9 → 替换tail[0] → tail = [10]
处理15: 15>=10 → 替换tail[0] → tail = [15]
处理20: 20>=15 → 替换tail[0] → tail = [20]
  1. 结果:tail长度=1(只能选一本书)

示例3:输入[[5,4],[6,4],[6,7],[7,3]]

  1. 排序处理
  • 长度降序:[7,3], [6,7], [6,4], [5,4]
  • 长度相同时按宽度降序:[7,3], [6,7], [6,4], [5,4]
  • 宽度序列:[3,7,4,4]
  1. 构建tail序列
处理3: tail = [3]
处理7: 7>=3 → 替换tail[0] → tail = [7]
处理4: 4<7 → tail = [7,4]
处理4: 4>=4 → 替换第一个>=4的位置(tail[1]) → tail = [7,4]
  1. 结果:tail长度=2(如[6,7]和[5,4])

总结

关键要点

  1. 排序预处理
  • 按长度降序确保长度关系
  • 长度相同时按宽度降序避免冲突
  1. 问题转化
  • 二维问题转化为一维序列问题
  • 寻找最长严格递减子序列
  1. 二分优化
  • 维护最小末尾值序列
  • 保证序列的严格递减性

应用场景

  1. 俄罗斯套娃问题
  2. 装箱问题
  3. 任务调度依赖
  4. 资源分配优化
  5. 游戏物体堆叠系统

该解法通过巧妙的排序策略将二维问题转化为一维问题,再利用二分查找优化经典动态规划算法,高效解决了书籍叠放问题。算法在保证正确性的同时具有良好的时间复杂度,适用于大规模数据处理。

http://www.dtcms.com/a/301172.html

相关文章:

  • Coze Studio概览(一)
  • 力扣131:分割回文串
  • 详解赛灵思SRIO IP并提供一种FIFO封装SRIO的收发控制器仿真验证
  • 2025年Agent创业实战指南:从0到1打造高增长AI智能体项目
  • FPGA IP升级
  • input_handler和input_dev详解
  • 【AI阅读】20250717阅读输入
  • 深度学习在计算机视觉中的应用:对象检测
  • C++ auto 类型推导
  • Netty中 ? extends Future<? super V>这种的写法的理解
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 73(题目+回答)
  • PDF文件被加密限制怎么办?专业级解除方案分享
  • mysql 快速上手
  • FFmpeg——参数详解
  • 3.JDK+JRE组件构成与协作
  • LeetCode 923.多重三数之和
  • 【AI论文】WebShaper:通过信息寻求形式化实现主动式数据合成
  • CIFAR100数据集实测-基于 AlexNet模型的压缩/Bagging/Boosting 探索
  • 创建的springboot工程java文件夹下还是文件夹而不是包
  • 大数据之路:阿里巴巴大数据实践——大数据领域建模综述
  • 卷积神经网络研讨
  • haproxy七层代理(知识点+相关实验部署)
  • 【奔跑吧!Linux 内核(第二版)】第5章:内核模块
  • 关系与逻辑运算 —— 寄存器操作的 “入门钥匙”
  • Linux: 调试器gdb/cgdb
  • 第六章 JavaScript 互操(2).NET调用JS
  • K-近邻算法
  • MPLS LDP(概念)
  • 20250707-2-Kubernetes 网络-Ingress暴露应用(http与https)_笔记
  • Flink窗口:解锁流计算的秘密武器