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 分别追踪当前处理的水平区域的高度和垂直区域的宽度。
  • 通过比较当前处理的切割线位置,决定先处理哪一条切割线,并计算相应的成本。
  • 最终返回所有切割操作所需的最小成本。
相关推荐
容辞2 小时前
算法-贪婪算法
算法·贪心算法
Evand J2 小时前
MATLAB程序演示与编程思路,相对导航,四个小车的形式,使用集中式扩展卡尔曼滤波(fullyCN-EKF)
人工智能·算法
椰萝Yerosius4 小时前
[题解]2023CCPC黑龙江省赛 - Ethernet
算法·深度优先
IT猿手4 小时前
基于 Q-learning 的城市场景无人机三维路径规划算法研究,可以自定义地图,提供完整MATLAB代码
深度学习·算法·matlab·无人机·强化学习·qlearning·无人机路径规划
竹下为生6 小时前
LeetCode --- 448 周赛
算法·leetcode·职场和发展
未名编程6 小时前
LeetCode 88. 合并两个有序数组 | Python 最简写法 + 实战注释
python·算法·leetcode
Cuit小唐7 小时前
C++ 迭代器模式详解
c++·算法·迭代器模式
2401_858286117 小时前
CD37.【C++ Dev】string类的模拟实现(上)
开发语言·c++·算法
CQY05317 小时前
蓝桥杯2025年第十六届省赛真题-水质检测
职场和发展·蓝桥杯
╭⌒心岛初晴7 小时前
JAVA练习题(2) 找素数
java·开发语言·算法·java练习题·判断素数/质数