Leetcode 1240:铺瓷砖(超详细的解法!!!)

2023-10-16 19:59

本文主要是介绍Leetcode 1240:铺瓷砖(超详细的解法!!!),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

你是一位施工队的工长,根据设计师的要求准备为一套设计风格独特的房子进行室内装修。

房子的客厅大小为 n x m,为保持极简的风格,需要使用尽可能少的 正方形 瓷砖来铺盖地面。

假设正方形瓷砖的规格不限,边长都是整数。

请你帮设计师计算一下,最少需要用到多少块方形瓷砖?

示例 1:

输入:n = 2, m = 3
输出:3
解释:3 块地砖就可以铺满卧室。2 块 1x1 地砖1 块 2x2 地砖

示例 2:

输入:n = 5, m = 8
输出:5

示例 3:

输入:n = 11, m = 13
输出:6

提示:

  • 1 <= n <= 13
  • 1 <= m <= 13

解题思路

这是一个经典的问题,该问题源自这篇论文Tiling a rectangle with the fewest squares。当然我们这里肯定不会这么复杂的去做,这里给出两种解法。

首先考虑dfs的解法,也就是一行一行的去枚举可以放的矩形,例如:

此时我们将第一行的所有矩形都确定了,接着考虑第二行的矩形,那么这里应该是从绿色(第2个)下面开始放,然后再放紫色的(第4个),也就是从最低高度开始放。当所有矩形的高度都是大矩形的高度n时,那么此时摆放成功,记录结果。为了记录每个矩形的高度,我们需要开辟m大小的数组(记录每个位置的高度)。对于第一个例子,最后记录(最后一层)的就是[1,2,2]。需要注意的是,我们实际放正方形的时候采用贪心策略(从最大的开始放),所以并不会出现上图中的情形。

最后代码非常简洁:

class Solution:def tilingRectangle(self, n: int, m: int) -> int:res = m * n    def dfs(ht, moves):if all(h == n for h in ht):res = min(res, moves)returnif moves >= res:returnidx = ht.index(min(ht))for i in range(min(m - idx, n - ht[idx]), 0, -1):# 正方形大小nht = ht[:]for j in range(i): # 正方形放入nht[idx + j] += idfs(nht, moves + 1) dfs([0] * m, 0)return res

这个问题还可以换一种方式思考,仔细观察题目给的例子,实际上描述了三种切分方式:横切、竖切和包含中心正方形的切分(第三个图)。

对于横切来说,最后的结果就应该来自上面一个矩形和下面一个矩形;对于竖切来说,最后的结果就应该来自左边一个矩形和右边一个矩形;对于包含正方形的形式来说,可以看成下面这种方式:

将左上角两个正方形何在一起看,我们需要确定中心矩形的大小l和位置(i,j),那么左上角矩形的大小就是(i+l,j),右上角矩形的大小就是(x-(i+l),j+l),左下角矩形的大小就是(i,y-j),右下角矩形的大小就是(x-i,y-(j+l)),其中xy表示外部整个矩形的宽度和高度。

接着思考边界问题,当x==y的时候,只要一个正方形就可以了。而当x==1的时候,需要y个正方形。当y==1的时候,需要x个正方形。

from functools import lru_cache
class Solution:def tilingRectangle(self, n: int, m: int) -> int:@lru_cache(None)def dfs(x, y):if x == y:return 1if x == 1:return yif y == 1:return xres = x * yfor i in range(1, x//2 + 1):# 竖切res = min(res, dfs(i, y) + dfs(x - i, y))for j in range(1, y//2 + 1):# 横切res = min(res, dfs(x, j) + dfs(x, y - j))for l in range(1, min(x, y)):# 包含中心for i in range(1, x-l):for j in range(1, y-l):res = min(res, dfs(i+l, j) + dfs(x-(i+l), j+l) + dfs(i, y-j) + dfs(x-i, y-(j+l)) + 1)return resreturn dfs(n, m)

上面这个代码还可以继续优化,我们可以去掉包含中心的情况。因为题目给的数据最大是13,而包含中心矩形的最优解只会出现在(11,13)(13,11)这两种情况的时候,此时的最优解是6,可以查看这个表。

from functools import lru_cache
class Solution:def tilingRectangle(self, n: int, m: int) -> int:@lru_cache(None)def dfs(x, y):if (x, y) in {(11, 13), (13, 11)}:return 6if x == y:return 1res = x * yfor i in range(1, x//2 + 1):res = min(res, dfs(i, y) + dfs(x - i, y))for j in range(1, y//2 + 1):res = min(res, dfs(x, j) + dfs(x, y - j))return resreturn dfs(n, m)

reference:

https://www.bilibili.com/video/av73704545?from=search&seid=6528127797779899524

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

这篇关于Leetcode 1240:铺瓷砖(超详细的解法!!!)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/220467

相关文章

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++