Leetcode打卡:切蛋糕的最小总开销II

执行结果:通过

题目 3219 切蛋糕的最小总开销II

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

给你整数 mn 和两个数组:

  • 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 <= 105
  • horizontalCut.length == m - 1
  • verticalCut.length == n - 1
  • 1 <= horizontalCut[i], verticalCut[i] <= 103

代码以及解题思路

代码:

复制代码
int compare(const void* a, const void* b) {
    return (*(int*)b - *(int*)a);
}
long long minimumCost(int m, int n, int* horizontalCut, int horizontalCutSize, int* verticalCut, int verticalCutSize) {
     qsort(horizontalCut, horizontalCutSize, sizeof(int), compare);
    qsort(verticalCut, verticalCutSize, sizeof(int), compare);
    long long h = 1, v = 1;
    long long res = 0;
    int hIndex = 0, vIndex = 0;
    while (hIndex < horizontalCutSize || vIndex < verticalCutSize) {
        if (vIndex == verticalCutSize || (hIndex < horizontalCutSize && horizontalCut[hIndex] > verticalCut[vIndex])) {
            res += horizontalCut[hIndex++] * h;
            v++;
        } else {
            res += verticalCut[vIndex++] * v;
            h++;
        }
    }
    return res;

}

解题思路:

  1. 排序切割线
    • 使用 qsort 函数对 horizontalCutverticalCut 数组进行排序。compare 函数确保了排序是按照降序进行的,这对于后续步骤中的比较和计算至关重要。排序的目的是为了方便处理切割线,确保在计算成本时,我们可以按顺序处理水平切割线和垂直切割线。
  2. 初始化变量
    • hv 分别表示当前处理到的水平区域的高度和垂直区域的宽度。初始时,整个蛋糕是一个完整的区域,所以高度和宽度均为1。
    • res 用于累加总的切割成本。
    • hIndexvIndex 分别表示当前处理的水平切割线和垂直切割线的索引。
  3. 遍历切割线
    • 使用 while 循环遍历所有的切割线。循环条件是 hIndex < horizontalCutSize || vIndex < verticalCutSize,意味着只要还有未处理的切割线,就继续循环。
    • 在循环内部,通过比较当前处理的水平切割线和垂直切割线的位置,决定先处理哪一条切割线。由于切割线数组是降序排序的,所以可以直接通过比较当前索引对应的切割线位置来决定。
    • 如果先处理水平切割线,那么将该切割线对应的面积(horizontalCut[hIndex] * h)加到总成本 res 上,并将水平区域的计数 h 加1,表示现在处理的是下一个水平区域。同时,水平切割线索引 hIndex 自增。
    • 如果先处理垂直切割线,那么操作类似,只不过是将垂直区域的宽度 v 加1,并更新垂直切割线索引 vIndex
  4. 返回结果
    • 当所有的切割线都被处理后,循环结束,返回累加的总成本 res

总结:

  • 代码通过排序确保切割线按顺序处理。
  • 使用两个变量 hv 分别追踪当前处理的水平区域的高度和垂直区域的宽度。
  • 通过比较当前处理的切割线位置,决定先处理哪一条切割线,并计算相应的成本。
  • 最终返回所有切割操作所需的最小成本。
相关推荐
焦耳加热1 小时前
阿德莱德大学Nat. Commun.:盐模板策略实现废弃塑料到单原子催化剂的高值转化,推动环境与能源催化应用
人工智能·算法·机器学习·能源·材料工程
wan5555cn1 小时前
多张图片生成视频模型技术深度解析
人工智能·笔记·深度学习·算法·音视频
u6062 小时前
常用排序算法核心知识点梳理
算法·排序
蒋星熠4 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
小欣加油4 小时前
leetcode 面试题01.02判定是否互为字符重排
数据结构·c++·算法·leetcode·职场和发展
3Cloudream4 小时前
LeetCode 003. 无重复字符的最长子串 - 滑动窗口与哈希表详解
算法·leetcode·字符串·双指针·滑动窗口·哈希表·中等
王璐WL4 小时前
【c++】c++第一课:命名空间
数据结构·c++·算法
空白到白5 小时前
机器学习-聚类
人工智能·算法·机器学习·聚类
索迪迈科技5 小时前
java后端工程师进修ing(研一版 || day40)
java·开发语言·学习·算法
zzzsde5 小时前
【数据结构】队列
数据结构·算法