100361. 切蛋糕的最小总开销 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
解释:
3 x 1
的蛋糕块,开销为 1 。3 x 1
的蛋糕块,开销为 1 。2 x 1
的蛋糕块,开销为 3 。2 x 1
的蛋糕块,开销为 3 。总开销为 5 + 1 + 1 + 3 + 3 = 13
。
示例 2:
输入:m = 2, n = 2, horizontalCut = [7], verticalCut = [4]
输出:15
解释:
1 x 2
的蛋糕块,开销为 4 。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
原站题解
php 解法, 执行用时: 10 ms, 内存消耗: 20.2 MB, 提交时间: 2024-07-15 10:18:38
class Solution { /** * @param Integer $m * @param Integer $n * @param Integer[] $horizontalCut * @param Integer[] $verticalCut * @return Integer */ function minimumCost($m, $n, $horizontalCut, $verticalCut) { // 排序横切和竖切数组 sort($horizontalCut); sort($verticalCut); $ans = 0; $i = $m - 2; // 因为最后一块不需要切,所以从倒数第二块开始 $j = $n - 2; // 同理 while ($i >= 0 || $j >= 0) { if ($j < 0 || ($i >= 0 && $horizontalCut[$i] > $verticalCut[$j])) { // 横切 $ans += $horizontalCut[$i] * ($n - 1 - $j); $i--; } else { // 竖切 $ans += $verticalCut[$j] * ($m - 1 - $i); $j--; } } return $ans; } }
javascript 解法, 执行用时: 86 ms, 内存消耗: 51.1 MB, 提交时间: 2024-07-15 10:13:23
/** * @param {number} m * @param {number} n * @param {number[]} horizontalCut * @param {number[]} verticalCut * @return {number} */ var minimumCost = function(m, n, horizontalCut, verticalCut) { // 对横切和竖切数组进行排序,从大到小 horizontalCut.sort((a, b) => b - a); verticalCut.sort((a, b) => b - a); let ans = 0; let cntH = 1; // 需要横切的蛋糕块数 let cntV = 1; // 需要竖切的蛋糕块数 let i = 0; // 横切数组的索引 let j = 0; // 竖切数组的索引 // 循环直到所有的横切和竖切都被处理 while (i < m - 1 || j < n - 1) { if (j === n - 1 || (i < m - 1 && horizontalCut[i] > verticalCut[j])) { // 横切 ans += horizontalCut[i] * cntH; i++; cntV++; // 竖切的蛋糕块数增加 } else { // 竖切 ans += verticalCut[j] * cntV; j++; cntH++; // 横切的蛋糕块数增加 } } return ans; };
golang 解法, 执行用时: 2 ms, 内存消耗: 2.5 MB, 提交时间: 2024-07-15 10:10:50
func minimumCost1(m, n int, horizontalCut, verticalCut []int) int { slices.SortFunc(horizontalCut, func(a, b int) int { return b - a }) slices.SortFunc(verticalCut, func(a, b int) int { return b - a }) ans := 0 cntH, cntV := 1, 1 i, j := 0, 0 for i < m-1 || j < n-1 { if j == n-1 || i < m-1 && horizontalCut[i] > verticalCut[j] { ans += horizontalCut[i] * cntH // 横切 i++ cntV++ // 需要竖切的蛋糕块增加 } else { ans += verticalCut[j] * cntV // 竖切 j++ cntH++ // 需要横切的蛋糕块增加 } } return ans } // 优化 func minimumCost(m, n int, horizontalCut, verticalCut []int) int { slices.SortFunc(horizontalCut, func(a, b int) int { return b - a }) slices.SortFunc(verticalCut, func(a, b int) int { return b - a }) ans := 0 i, j := 0, 0 for i < m-1 || j < n-1 { if j == n-1 || i < m-1 && horizontalCut[i] > verticalCut[j] { ans += horizontalCut[i] * (j + 1) // 横切 i++ } else { ans += verticalCut[j] * (i + 1) // 竖切 j++ } } return ans }
java 解法, 执行用时: 1 ms, 内存消耗: 41 MB, 提交时间: 2024-07-15 10:08:59
class Solution { public int minimumCost1(int m, int n, int[] horizontalCut, int[] verticalCut) { Arrays.sort(horizontalCut); // 下面倒序遍历 Arrays.sort(verticalCut); int ans = 0; int i = m - 2; int j = n - 2; int cntH = 1; int cntV = 1; while (i >= 0 || j >= 0) { if (j < 0 || i >= 0 && horizontalCut[i] > verticalCut[j]) { ans += horizontalCut[i--] * cntH; // 横切 cntV++; // 需要竖切的蛋糕块增加 } else { ans += verticalCut[j--] * cntV; // 竖切 cntH++; // 需要横切的蛋糕块增加 } } return ans; } // 优化 public int minimumCost(int m, int n, int[] horizontalCut, int[] verticalCut) { Arrays.sort(horizontalCut); // 下面倒序遍历 Arrays.sort(verticalCut); int ans = 0; int i = m - 2; int j = n - 2; while (i >= 0 || j >= 0) { if (j < 0 || i >= 0 && horizontalCut[i] > verticalCut[j]) { ans += horizontalCut[i--] * (n - 1 - j); // 横切 } else { ans += verticalCut[j--] * (m - 1 - i); // 竖切 } } return ans; } }
cpp 解法, 执行用时: 8 ms, 内存消耗: 28.9 MB, 提交时间: 2024-07-15 10:06:33
class Solution { public: long long minimumCost1(int m, int n, vector<int>& horizontalCut, vector<int>& verticalCut) { ranges::sort(horizontalCut, greater<>()); ranges::sort(verticalCut, greater<>()); long long ans = 0; int cnt_h = 1, cnt_v = 1; int i = 0, j = 0; while (i < m - 1 || j < n - 1) { if (j == n - 1 || i < m - 1 && horizontalCut[i] > verticalCut[j]) { ans += horizontalCut[i++] * cnt_h; // 横切 cnt_v++; // 需要竖切的蛋糕块增加 } else { ans += verticalCut[j++] * cnt_v; // 竖切 cnt_h++; // 需要横切的蛋糕块增加 } } return ans; } // 优化 long long minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>& verticalCut) { ranges::sort(horizontalCut, greater<>()); ranges::sort(verticalCut, greater<>()); long long ans = 0; int i = 0, j = 0; while (i < m - 1 || j < n - 1) { if (j == n - 1 || i < m - 1 && horizontalCut[i] > verticalCut[j]) { ans += horizontalCut[i++] * (j + 1); // 横切 } else { ans += verticalCut[j++] * (i + 1); // 竖切 } } return ans; } };
python3 解法, 执行用时: 44 ms, 内存消耗: 16.5 MB, 提交时间: 2024-07-15 10:05:33
class Solution: # 谁开销大,先切谁,留到后面只会开销更大 def minimumCost1(self, m: int, n: int, horizontalCut: List[int], verticalCut: List[int]) -> int: horizontalCut.sort(reverse=True) verticalCut.sort(reverse=True) ans = i = j = 0 cnt_h = cnt_v = 1 while i < m - 1 or j < n - 1: if j == n - 1 or i < m - 1 and horizontalCut[i] > verticalCut[j]: ans += horizontalCut[i] * cnt_h # 横切 i += 1 cnt_v += 1 # 需要竖切的蛋糕块增加 else: ans += verticalCut[j] * cnt_v # 竖切 j += 1 cnt_h += 1 # 需要横切的蛋糕块增加 return ans # 优化 def minimumCost(self, m: int, n: int, horizontalCut: List[int], verticalCut: List[int]) -> int: horizontalCut.sort(reverse=True) verticalCut.sort(reverse=True) ans = i = j = 0 while i < m - 1 or j < n - 1: if j == n - 1 or i < m - 1 and horizontalCut[i] > verticalCut[j]: ans += horizontalCut[i] * (j + 1) # 横切 i += 1 else: ans += verticalCut[j] * (i + 1) # 竖切 j += 1 return ans