LeetCode 1105. 填充书架

devtools/2025/3/25 2:33:28/

LeetCode 1105. 填充书架

题目描述

给定一个数组 books,其中 books[i] = [thicknessi, heighti] 表示第 i 本书的厚度和高度。你也会得到一个整数 shelfWidth,表示书架的总宽度。

按顺序将这些书摆放到总宽度为 shelfWidth 的书架上。你可以先选择几本书放在书架上(它们的厚度之和小于等于书架的宽度 shelfWidth),然后再建立一层书架。重复这个过程,直到把所有的书都放在书架上。

需要注意的是,在上述过程的每个步骤中,摆放书的顺序与给定图书数组 books 顺序相同。

每一层所摆放的书的最大高度就是这一层书架的层高,书架整体的高度为各层高之和。

要求: 返回书架整体可能的最小高度。

示例

示例 1:

输入: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelfWidth = 4
输出: 6
解释:
3 层书架的高度和为 1 + 3 + 2 = 6。
第 2 本书不必放在第一层书架上。

示例 2:

输入: books = [[1,3],[2,4],[3,2]], shelfWidth = 6
输出: 4

思路

本题是一个典型的动态规划问题。我们需要通过选择合适的方式将书本摆放到书架上,目标是最小化书架的总高度。

解题步骤:

  1. 定义状态:
    dp[i] 表示将前 i 本书放入书架所需的最小总高度。

  2. 状态转移:

    • 对于每一层书架,我们尝试放置从第 j 本书到第 i 本书(1 ≤ j ≤ i),并保证放置的书的总厚度不超过 shelfWidth
    • 设定一个变量 width 用于记录当前层书架的宽度,height 用于记录当前层书架的高度。对于每一层书架,我们从第 j 本书开始,依次加入书本,直到总厚度超过 shelfWidth
    • 当我们添加新的书本时,更新当前层书架的最大高度,并将该层书架的高度加到 dp[j-1] 上,更新 dp[i]
  3. 最终结果:
    最终的结果存储在 dp[n],其中 n 是书本的总数,表示所有书本都放入书架所需的最小总高度。

代码实现:

def minHeightShelves(books, shelfWidth):n = len(books)dp = [float('inf')] * (n + 1)  # dp[i]表示前i本书的最小高度dp[0] = 0  # 没有书时,书架的高度为0# 遍历每一本书for i in range(1, n + 1):width = 0  # 当前书架的宽度height = 0  # 当前书架的高度# 尝试从第j本书到第i本书放在同一层for j in range(i, 0, -1):width += books[j - 1][0]  # 加上当前书的厚度if width > shelfWidth:  # 如果宽度超过了书架的最大宽度,跳出breakheight = max(height, books[j - 1][1])  # 更新当前层书架的最大高度dp[i] = min(dp[i], dp[j - 1] + height)  # 更新最小高度return dp[n]

解释:

  1. 初始化:

    • dp[0] = 0,表示没有书时,书架的高度为 0。
    • 其他 dp[i] 初始值设置为无穷大,表示初始时无法计算的状态。
  2. 状态转移:

    • 对于每一本书,从当前位置 i 向前遍历每个可能的起点 j,计算从第 j 本书到第 i 本书放在同一层书架上的最小高度。
    • width 累加每一本书的厚度,如果超过 shelfWidth 则跳出。
    • height 记录当前层书架的最大高度。
    • 更新 dp[i],即当前放书方式的最小总高度。
  3. 结果:
    最终,dp[n] 就是将所有书按顺序放到书架上所需的最小高度。

时间复杂度

  • 外层循环遍历每本书 i,内层循环遍历可能的起始位置 j。每次计算时,时间复杂度为 O(n),所以总体时间复杂度是 O(n^2)。

总结

本题的关键在于动态规划的设计,如何利用 dp[i] 记录前 i 本书的最小高度,并通过状态转移更新最优解。通过不断尝试不同的层数和放置方式,可以得到最小的书架高度。


http://www.ppmy.cn/devtools/168541.html

相关文章

如何在 Github 上获得 1000 star?

作为程序员,Github 是第一个绕不开的网站。我们每天都在上面享受着开源带来的便利,我相信很多同学也想自己做一个开源项目,从而获得大家的关注。然而,理想很丰满,现实却是开发了很久的项目仍然无人问津。 最近&#x…

在使用mybatis时遇到枚举的相关问题和解决

目录 1.前言 2.问题解决 2.1 在父依赖中添加版本管理 2.2 微服务中引入依赖 2.3 在application.yaml中进行配置 2.4 在枚举中添加注解 1.前言 今天在使用mybatis的时候,如下SQL查询遇到了报错(其中status为枚举类型,数据库中存的为整形)&#xf…

排序算法-选择排序

选择排序的思路 基本思路步骤: 遍历数组: 从数组的起始位置开始,将第一个元素视为当前最小(或最大)的元素。 找到最小(或最大)元素: 遍历未排序的部分,找到比当前最小&a…

格力地产更名“珠免集团“ 全面转型免税赛道

大湾区经济网品牌观察讯,3月18日,格力地产股份有限公司公告宣布,拟将公司名称变更为"珠海珠免集团股份有限公司",证券简称同步变更为"珠免集团"。此次更名并非简单的品牌焕新,而是标志着这家曾以房…

前端---初识HTML(前端三剑客)

1.HTML 先为大家介绍几个学习前端的网站:菜鸟教程,w3school,CSS HTML:超文本标记语言 超⽂本: ⽐⽂本要强⼤. 通过链接和交互式⽅式来组织和呈现信息的⽂本形式. 不仅仅有⽂本, 还可能包含图⽚, ⾳频, 或者⾃已经审阅过它的学者…

AI建模智能生成:从2D到3D,AI只需一步!

传统3D建模过程既复杂又耗时,要经过建模、贴图、渲染等一系列操作,需要设计师具备深厚的专业技能,同时也要投入大量的时间精力,即便是经验丰富的专业人士,制作一个3D模型也需要历经数小时乃至数日的精心雕琢。 而随着A…

QT学习笔记1

** Qt Creator开发环境配置** 安装流程(Windows平台) 下载与安装 : 访问Qt官网,下载在线安装工具Qt Online Installer。登录或注册Qt账号,选择开源版本(需勾选“接受协议”)。勾选组件&#xff…

vim在连续多行行首插入相同的字符

工作中经常需要用vim注释掉一段代码或者json文件中的一部分,需要在多行前面插入//或者#符号。在 Vim 中,在连续多行行首插入相同字符主要有以下两种方法: Visual Block 模式插入 将光标移到要插入相同内容的第一行的行首24。按下Ctrl v进入…