Leetcode打卡:切蛋糕的最小总开销I
执行结果:通过
题目 3218 切蛋糕的最小总开销I
有一个 m x n
大小的矩形蛋糕,需要切成 1 x 1
的小块。
给你整数 m
,n
和两个数组:
horizontalCut
的大小为m - 1
,其中horizontalCut[i]
表示沿着水平线i
切蛋糕的开销。verticalCut
的大小为n - 1
,其中verticalCut[j]
表示沿着垂直线j
切蛋糕的开销。
一次操作中,你可以选择任意不是 1 x 1
大小的矩形蛋糕并执行以下操作之一:
- 沿着水平线
i
切开蛋糕,开销为horizontalCut[i]
。 - 沿着垂直线
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
代码以及解题思路
代码
int cmp(const void * a, const void * b) {
return * (int *) b - * (int *) a;
}
int minimumCost(int m, int n, int* horizontalCut, int horizontalCutSize, int* verticalCut, int verticalCutSize) {
qsort(horizontalCut, horizontalCutSize, sizeof(int), cmp);
qsort(verticalCut , verticalCutSize , sizeof(int), cmp);
int i = 0, j = 0, ans = 0;
while (i < horizontalCutSize && j < verticalCutSize)
ans += horizontalCut[i] > verticalCut[j] ? horizontalCut[i ++] * (j + 1) : verticalCut[j ++] * (i + 1);
while (i < horizontalCutSize) ans += horizontalCut[i ++] * n;
while (j < verticalCutSize) ans += verticalCut[j ++] * m;
return ans;
}
解题思路:
- 排序切割线:
- 使用
qsort
函数对horizontalCut
和verticalCut
数组进行排序。这里自定义的比较函数cmp
实现了降序排序(从大到小),因为切割线的位置越大,表示离边缘越远,通常意味着更高的成本。 - 排序是为了便于后续计算最小成本,因为这样可以保证在遍历切割线时,每次遇到的最大切割线(即成本最高的切割线)都是当前遍历到的最远的切割线。
- 使用
- 计算最小成本:
- 初始化两个指针
i
和j
分别用于遍历horizontalCut
和verticalCut
数组。 - 初始化变量
ans
用于存储最小成本。 - 使用一个
while
循环,直到任一指针遍历完其对应的切割线数组。在每次迭代中,比较当前horizontalCut[i]
和verticalCut[j]
的值:- 如果
horizontalCut[i]
更大,表示当前最大的水平切割线更远,因此应该首先进行这条水平切割。由于此时所有的垂直切割线都在这条水平切割线下方,所以这条水平切割线会将下方的所有小矩形都分割一次,成本为horizontalCut[i] * (j + 1)
(因为已经有j + 1
条垂直切割线)。 - 如果
verticalCut[j]
更大,同理,应该首先进行垂直切割,成本为verticalCut[j] * (i + 1)
。
- 如果
- 更新
i
或j
指针,以继续遍历剩余的切割线。 - 当任一指针遍历完其数组后,剩余未处理的切割线(无论是水平还是垂直)都将直接切割到蛋糕的另一边缘。因此,对于剩余的
horizontalCut
中的切割线,每条的成本为horizontalCut[i] * n
(因为每条水平线都会切割整个宽度n
);对于剩余的verticalCut
中的切割线,每条的成本为verticalCut[j] * m
(因为每条垂直线都会切割整个高度m
)。
- 初始化两个指针
- 返回最小成本:
- 循环结束后,
ans
存储了将蛋糕切割成小块的最小成本,返回这个值。
- 循环结束后,
原文地址:https://blog.csdn.net/m0_69493801/article/details/144707835
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!