LeetCode 3218.切蛋糕的最小总开销 I:记忆化搜索(深度优先搜索DFS)

embedded/2024/12/26 20:49:10/

【LetMeFly】3218.切蛋糕的最小总开销 I:记忆化搜索(深度优先搜索DFS)

力扣题目链接:https://leetcode.cn/problems/minimum-cost-for-cutting-cake-i/

有一个 m x n 大小的矩形蛋糕,需要切成 1 x 1 的小块。

给你整数 m ,n 和两个数组:

  • horizontalCut 的大小为 m - 1 ,其中 horizontalCut[i] 表示沿着水平线 i 切蛋糕的开销。
  • verticalCut 的大小为 n - 1 ,其中 verticalCut[j] 表示沿着垂直线 j 切蛋糕的开销。

一次操作中,你可以选择任意不是 1 x 1 大小的矩形蛋糕并执行以下操作之一:

  1. 沿着水平线 i 切开蛋糕,开销为 horizontalCut[i] 。
  2. 沿着垂直线 j 切开蛋糕,开销为 verticalCut[j] 。

每次操作后,这块蛋糕都被切成两个独立的小蛋糕。

每次操作的开销都为最开始对应切割线的开销,并且不会改变。

请你返回将蛋糕全部切成 1 x 1 的蛋糕块的 最小 总开销。

 

示例 1:

输入:m = 3, n = 2, horizontalCut = [1,3], verticalCut = [5]

输出:13

解释:

  • 沿着垂直线 0 切开蛋糕,开销为 5 。
  • 沿着水平线 0 切开 3 x 1 的蛋糕块,开销为 1 。
  • 沿着水平线 0 切开 3 x 1 的蛋糕块,开销为 1 。
  • 沿着水平线 1 切开 2 x 1 的蛋糕块,开销为 3 。
  • 沿着水平线 1 切开 2 x 1 的蛋糕块,开销为 3 。

总开销为 5 + 1 + 1 + 3 + 3 = 13 。

示例 2:

输入:m = 2, n = 2, horizontalCut = [7], verticalCut = [4]

输出:15

解释:

  • 沿着水平线 0 切开蛋糕,开销为 7 。
  • 沿着垂直线 0 切开 1 x 2 的蛋糕块,开销为 4 。
  • 沿着垂直线 0 切开 1 x 2 的蛋糕块,开销为 4 。

总开销为 7 + 4 + 4 = 15 。

 

提示:

  • 1 <= m, n <= 20
  • horizontalCut.length == m - 1
  • verticalCut.length == n - 1
  • 1 <= horizontalCut[i], verticalCut[i] <= 103

解题方法:深度优先搜索(记忆化)

写一个函数dfs计算:切割竖直方向[ia, ib)水平方向[ja, jb)这个子蛋糕所需的最小花费。

每次计算很简单,若已经是1x1大小则直接返回0,若是水平切割:

枚举所有水平切割的下刀位置。其中,递归计算上下两块新蛋糕所需的最小花费并加上这一刀的花费作为这种切割方法的最小花费。

若是竖直切割则同理。

直接使用整块大蛋糕的大小调用dfs函数即可求得答案。

  • 时间复杂度 O ( m 2 n 2 ( m + n ) ) O(m^2n^2(m+n)) O(m2n2(m+n))。共有 m 2 n 2 m^2n^2 m2n2种子蛋糕方案,每种方案首次计算平均耗时 O ( m + n ) O(m+n) O(m+n)
  • 空间复杂度 O ( m 2 n 2 ) O(m^2n^2) O(m2n2)

AC代码

C++
/** @Author: LetMeFly* @Date: 2024-12-25 18:08:17* @LastEditors: LetMeFly.xyz* @LastEditTime: 2024-12-25 18:40:56*/
class Solution {
private:unordered_map<int, int> ma;int dfs(int ia, int ib, int ja, int jb, vector<int>& h, vector<int>& v) {int code = ia + ib * 20 + ja * 400 + jb * 8000;if (ma.count(code)) {return ma[code];}int ans = 1000000000;if (ib - ia == 1 && jb - ja == 1) {ans = 0;}for (int ic = ia + 1; ic < ib; ic++) {ans = min(ans, h[ic - 1] + dfs(ia, ic, ja, jb, h, v) + dfs(ic, ib, ja, jb, h, v));}for (int jc = ja + 1; jc < jb; jc++) {ans = min(ans, v[jc - 1] + dfs(ia, ib, ja, jc, h, v) + dfs(ia, ib, jc, jb, h, v));}return ma[code] = ans;}
public:int minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>& verticalCut) {return dfs(0, m, 0, n, horizontalCut, verticalCut);}
};
Python
'''
Author: LetMeFly
Date: 2024-12-25 20:27:10
LastEditors: LetMeFly.xyz
LastEditTime: 2024-12-25 20:34:17
'''
from typing import List
from functools import cacheclass Solution:@cachedef dfs(self, ia: int, ib: int, ja: int, jb: int) -> int:if ib - ia == 1 and jb - ja == 1:return 0ans = 1000000000for ic in range(ia + 1, ib):ans = min(ans, self.h[ic - 1] + self.dfs(ia, ic, ja, jb) + self.dfs(ic, ib, ja, jb))for jc in range(ja + 1, jb):ans = min(ans, self.v[jc - 1] + self.dfs(ia, ib, ja, jc) + self.dfs(ia, ib, jc, jb))return ansdef minimumCost(self, m: int, n: int, horizontalCut: List[int], verticalCut: List[int]) -> int:self.h, self.v = horizontalCut, verticalCutreturn self.dfs(0, m, 0, n)
Java
/** @Author: LetMeFly* @Date: 2024-12-25 20:36:16* @LastEditors: LetMeFly.xyz* @LastEditTime: 2024-12-25 20:42:05*/
class Solution {int[][][][] cache;int[] h, v;private int dfs(int ia, int ib, int ja, int jb) {if (cache[ia][ib][ja][jb] > 0 || (ib == ia + 1 && jb == ja + 1)) {return cache[ia][ib][ja][jb];}int ans = 1000000000;for (int ic = ia + 1; ic < ib; ic++) {ans = Math.min(ans, h[ic - 1] + dfs(ia, ic, ja, jb) + dfs(ic, ib, ja, jb));}for (int jc = ja + 1; jc < jb; jc++) {ans = Math.min(ans, v[jc - 1] + dfs(ia, ib, ja, jc) + dfs(ia, ib, jc, jb));}cache[ia][ib][ja][jb] = ans;return ans;}public int minimumCost(int m, int n, int[] horizontalCut, int[] verticalCut) {cache = new int[m][m + 1][n][n + 1];h = horizontalCut;v = verticalCut;return dfs(0, m, 0, n);}
}
Go
/** @Author: LetMeFly* @Date: 2024-12-25 20:44:03* @LastEditors: LetMeFly.xyz* @LastEditTime: 2024-12-25 20:56:44*/
package mainfunc min_CFCC(a, b int) int {if a <= b {return a}return b
}func minimumCost(m int, n int, horizontalCut []int, verticalCut []int) int {cache := make([][][][]int, m)  // [m][m + 1][n][n + 1]for i := range cache {cache[i] = make([][][]int, m + 1)for j := range cache[i] {cache[i][j] = make([][]int, n)for k := range cache[i][j] {cache[i][j][k] = make([]int, n + 1)}}}var dfs func(int, int, int, int) intdfs = func(ia, ib, ja, jb int) int {if cache[ia][ib][ja][jb] > 0 || (ia == ib - 1 && ja == jb - 1) {return cache[ia][ib][ja][jb]}ans := 1000000000for ic := ia + 1; ic < ib; ic++ {ans = min_CFCC(ans, horizontalCut[ic - 1] + dfs(ia, ic, ja, jb) + dfs(ic, ib, ja, jb))}for jc := ja + 1; jc < jb; jc++ {ans = min_CFCC(ans, verticalCut[jc - 1] + dfs(ia, ib, ja, jc) + dfs(ia, ib, jc, jb))}cache[ia][ib][ja][jb] = ansreturn ans}return dfs(0, m, 0, n)
}

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/144728332


http://www.ppmy.cn/embedded/148993.html

相关文章

计算机网络:运输层 —— TCP 的选择确认(SACK)

文章目录 TCP 的选择确认协商与启用工作机制接收方发送方 TCP 的选择确认 在 TCP 传输过程中&#xff0c;由于网络拥塞、链路故障等因素&#xff0c;数据可能会出现丢失或乱序的情况。传统的 TCP 确认机制是累积确认&#xff0c;TCP 接收方只能对按序收到的数据中的最高序号给…

MongoDB部署高可用集群

一、准备工作 修改3台服务器的hostname为mongodb0、mongodb1和mongodb2 vim /etc/hostname vim /etc/hosts 分别配置3个节点的域名 10.5.30.19 mongodb0 10.5.30.14 mongodb1 10.5.30.18 mongodb2关闭防火墙下载mongodb安装包并解压:mongod…

arcface

GitHub - bubbliiiing/arcface-pytorch: 这是一个arcface-pytorch的源码&#xff0c;可以用于训练自己的模型。 https://github.com/deepinsight/insightface/tree/master/recognition/arcface_torch 参考博客 Arcface部署应用实战-CSDN博客 https://zhuanlan.zhihu.com/p/16…

威尔克斯(Wilks)分布

内容来源 应用多元统计分析 北京大学出版社 高惠璇编著 威尔克斯 Λ \Lambda Λ 分布 回顾一元统计中的 F F F 分布 设 ξ ∼ χ 2 ( m ) , η ∼ χ 2 ( n ) \xi\sim\chi^2(m),\eta\sim\chi^2(n) ξ∼χ2(m),η∼χ2(n)&#xff0c;且相互独立&#xff0c;则 F ξ / m η…

游戏引擎学习第59天

回顾并计划接下来的一天 在处理实体的空间划分时&#xff0c;遇到了一些问题。例如&#xff0c;虽然树和玩家应该在某些情况下被排除在外&#xff0c;但目前的系统仍然会出现不合逻辑的渲染结果&#xff0c;这在视觉上并不符合预期。尽管这些问题主要是渲染上的&#xff0c;并…

nacos-服务发现注册

服务发现注册分为三个角色&#xff1a;服务注册中心、服务提供者、服务消费者 服务注册中心&#xff1a;为服务提供者和消费者提供一个空间&#xff0c;服务提供者将自身服务注册到注册中心&#xff0c;仅对外暴露接口&#xff0c;服务消费者在将自身注册到注册中心的时候也会获…

C语言从入门到放弃教程

C语言从入门到放弃 1. 介绍1.1 特点1.2 历史与发展1.3 应用领域 2. 安装2.1 编译器安装2.2 编辑器安装 3. 第一个程序1. 包含头文件2. 主函数定义3. 打印语句4. 返回值 4. 基础语法4.1 注释4.1.1 单行注释4.1.2 多行注释 4.2 关键字4.2.1 C语言标准4.2.2 C89/C90关键字&#xf…

地理数据库Telepg面试内容整理-数据库设计与性能优化

在开发和维护 Telepg 地理数据库时,合理的数据库设计与性能优化是确保系统稳定、高效运行的关键。以下是针对数据库设计与优化的详细指南。 数据库设计原则 (1) 明确需求 ● 数据类型分析: ○ 确定需要存储的空间数据类型࿰