comments | difficulty | edit_url | rating | source | tags | |||
---|---|---|---|---|---|---|---|---|
true |
Hard |
1789 |
Weekly Contest 406 Q4 |
|
There is an m x n
cake that needs to be cut into 1 x 1
pieces.
You are given integers m
, n
, and two arrays:
horizontalCut
of sizem - 1
, wherehorizontalCut[i]
represents the cost to cut along the horizontal linei
.verticalCut
of sizen - 1
, whereverticalCut[j]
represents the cost to cut along the vertical linej
.
In one operation, you can choose any piece of cake that is not yet a 1 x 1
square and perform one of the following cuts:
- Cut along a horizontal line
i
at a cost ofhorizontalCut[i]
. - Cut along a vertical line
j
at a cost ofverticalCut[j]
.
After the cut, the piece of cake is divided into two distinct pieces.
The cost of a cut depends only on the initial cost of the line and does not change.
Return the minimum total cost to cut the entire cake into 1 x 1
pieces.
Example 1:
Input: m = 3, n = 2, horizontalCut = [1,3], verticalCut = [5]
Output: 13
Explanation:
- Perform a cut on the vertical line 0 with cost 5, current total cost is 5.
- Perform a cut on the horizontal line 0 on
3 x 1
subgrid with cost 1. - Perform a cut on the horizontal line 0 on
3 x 1
subgrid with cost 1. - Perform a cut on the horizontal line 1 on
2 x 1
subgrid with cost 3. - Perform a cut on the horizontal line 1 on
2 x 1
subgrid with cost 3.
The total cost is 5 + 1 + 1 + 3 + 3 = 13
.
Example 2:
Input: m = 2, n = 2, horizontalCut = [7], verticalCut = [4]
Output: 15
Explanation:
- Perform a cut on the horizontal line 0 with cost 7.
- Perform a cut on the vertical line 0 on
1 x 2
subgrid with cost 4. - Perform a cut on the vertical line 0 on
1 x 2
subgrid with cost 4.
The total cost is 7 + 4 + 4 = 15
.
Constraints:
1 <= m, n <= 105
horizontalCut.length == m - 1
verticalCut.length == n - 1
1 <= horizontalCut[i], verticalCut[i] <= 103
For a given position, the earlier you cut, the fewer cuts are needed, so it is clear that positions with higher costs should be cut earlier.
Therefore, we can sort the arrays
Each time a horizontal cut is made, if the number of columns before the cut was
Finally, when both
The time complexity is
class Solution:
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
h = 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] * v
h, i = h + 1, i + 1
else:
ans += verticalCut[j] * h
v, j = v + 1, j + 1
return ans
class Solution {
public long minimumCost(int m, int n, int[] horizontalCut, int[] verticalCut) {
Arrays.sort(horizontalCut);
Arrays.sort(verticalCut);
long ans = 0;
int i = m - 2, j = n - 2;
int h = 1, v = 1;
while (i >= 0 || j >= 0) {
if (j < 0 || (i >= 0 && horizontalCut[i] > verticalCut[j])) {
ans += 1L * horizontalCut[i--] * v;
++h;
} else {
ans += 1L * verticalCut[j--] * h;
++v;
}
}
return ans;
}
}
class Solution {
public:
long long minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>& verticalCut) {
sort(horizontalCut.rbegin(), horizontalCut.rend());
sort(verticalCut.rbegin(), verticalCut.rend());
long long ans = 0;
int i = 0, j = 0;
int h = 1, v = 1;
while (i < m - 1 || j < n - 1) {
if (j == n - 1 || (i < m - 1 && horizontalCut[i] > verticalCut[j])) {
ans += 1LL * horizontalCut[i++] * v;
h++;
} else {
ans += 1LL * verticalCut[j++] * h;
v++;
}
}
return ans;
}
};
func minimumCost(m int, n int, horizontalCut []int, verticalCut []int) (ans int64) {
sort.Sort(sort.Reverse(sort.IntSlice(horizontalCut)))
sort.Sort(sort.Reverse(sort.IntSlice(verticalCut)))
i, j := 0, 0
h, v := 1, 1
for i < m-1 || j < n-1 {
if j == n-1 || (i < m-1 && horizontalCut[i] > verticalCut[j]) {
ans += int64(horizontalCut[i] * v)
h++
i++
} else {
ans += int64(verticalCut[j] * h)
v++
j++
}
}
return
}
function minimumCost(m: number, n: number, horizontalCut: number[], verticalCut: number[]): number {
horizontalCut.sort((a, b) => b - a);
verticalCut.sort((a, b) => b - a);
let ans = 0;
let [i, j] = [0, 0];
let [h, v] = [1, 1];
while (i < m - 1 || j < n - 1) {
if (j === n - 1 || (i < m - 1 && horizontalCut[i] > verticalCut[j])) {
ans += horizontalCut[i] * v;
h++;
i++;
} else {
ans += verticalCut[j] * h;
v++;
j++;
}
}
return ans;
}