You are given two integers m
and n
that represent the height and width of a rectangular piece of wood. You are also given a 2D integer array prices
, where prices[i] = [hi, wi, pricei]
indicates you can sell a rectangular piece of wood of height hi
and width wi
for pricei
dollars.
To cut a piece of wood, you must make a vertical or horizontal cut across the entire height or width of the piece to split it into two smaller pieces. After cutting a piece of wood into some number of smaller pieces, you can sell pieces according to prices
. You may sell multiple pieces of the same shape, and you do not have to sell all the shapes. The grain of the wood makes a difference, so you cannot rotate a piece to swap its height and width.
Return the maximum money you can earn after cutting an m x n
piece of wood.
Note that you can cut the piece of wood as many times as you want.
Example 1:
Input: m = 3, n = 5, prices = [[1,4,2],[2,2,7],[2,1,3]] Output: 19 Explanation: The diagram above shows a possible scenario. It consists of: - 2 pieces of wood shaped 2 x 2, selling for a price of 2 * 7 = 14. - 1 piece of wood shaped 2 x 1, selling for a price of 1 * 3 = 3. - 1 piece of wood shaped 1 x 4, selling for a price of 1 * 2 = 2. This obtains a total of 14 + 3 + 2 = 19 money earned. It can be shown that 19 is the maximum amount of money that can be earned.
Example 2:
Input: m = 4, n = 6, prices = [[3,2,10],[1,4,2],[4,1,3]] Output: 32 Explanation: The diagram above shows a possible scenario. It consists of: - 3 pieces of wood shaped 3 x 2, selling for a price of 3 * 10 = 30. - 1 piece of wood shaped 1 x 4, selling for a price of 1 * 2 = 2. This obtains a total of 30 + 2 = 32 money earned. It can be shown that 32 is the maximum amount of money that can be earned. Notice that we cannot rotate the 1 x 4 piece of wood to obtain a 4 x 1 piece of wood.
Constraints:
1 <= m, n <= 200
1 <= prices.length <= 2 * 104
prices[i].length == 3
1 <= hi <= m
1 <= wi <= n
1 <= pricei <= 106
(hi, wi)
are pairwise distinct.This problem asks for the maximum amount of money you can earn by cutting a rectangular piece of wood into smaller pieces and selling them according to a given price list. We can solve this using either memoization (top-down dynamic programming) or dynamic programming (bottom-up). Both approaches have the same time and space complexity.
The core idea is to recursively explore all possible ways to cut the wood. For each cut, we consider the maximum profit obtainable from the resulting sub-rectangles. To avoid redundant calculations, we use either memoization (storing results of subproblems) or dynamic programming (iteratively building up solutions from smaller subproblems).
Initialization:
d
(or a hashmap equivalent in some languages) to store the prices of rectangular pieces directly from the prices
input. d[h][w]
stores the price of a piece with height h
and width w
. If no such piece exists in prices
, the value will be 0.f
(or a hashmap equivalent) to store the maximum profit for different sized wood pieces. f[h][w]
stores the maximum profit obtainable from a h x w
piece of wood.Iteration (Dynamic Programming):
h
) and widths (w
) from 1 to m
and 1 to n
respectively.f[h][w]
, we consider two types of cuts:
k
) from 1 to h - 1
. The maximum profit is the sum of the profits from the top and bottom parts: max(f[h][w], f[k][w] + f[h - k][w])
.k
) from 1 to w - 1
. The maximum profit is the sum of the profits from the left and right parts: max(f[h][w], f[h][k] + f[h][w - k])
.f[h][w]
with the maximum profit found among the initial price (d[h][w]
) and the profits from vertical and horizontal cuts.Memoization (Top-Down Dynamic Programming):
dfs(h, w)
that computes f[h][w]
.h
or w
is 0, returning 0.f[h][w]
has already been computed (i.e., it's not -1 or null, depending on the language), we return the stored value.f[h][w]
as described in step 2 above and store it before returning.Result:
m x n
piece of wood is stored in f[m][n]
.Time Complexity: O(m * n * (m + n) + p), where m
and n
are the dimensions of the wood and p
is the number of price entries. The dominant factor is the nested loops in both DP and memoization that explore all possible cuts.
Space Complexity: O(m * n). We use a 2D array f
(and potentially d
) to store the results, using O(m*n) space.
The code examples in Python, Java, C++, Go, and TypeScript are already provided in the problem statement. They implement either memoization or dynamic programming as described above. The choice between memoization and DP is often a matter of preference; memoization can be more concise for some, while DP is often considered slightly more efficient in some cases due to avoiding function call overhead.