Leetcode: 2312. Selling Pieces of Wood
Problem Statement: Given a rectangle of dimensions \(m \times n\) and tiles \(r[i]=[h_i, w_i, p_i]\) where \(h_i, w_i\) and \(p_i\) are the height, width and price of the \(i\)th tile, return the maximum coverage (sum of all prices of each tile used) of the given rectangles given that you always have to entirely cut the rectangle in horizontally or vertically.
We can formulate using the following recurrence:
\begin{equation*} f(h, w)=\begin{cases} 0, & \mbox{if $i = 0$ or $j = 0$} \\ \max(p(h, w), f(i, w) + f(h - i, w), f(h, j) + f(h, w - j)) & \mbox{for $1 \leq i < h$ and $1 \leq j < w$>}. \end{cases} \end{equation*}This recurrence has \(O(m \times n)\) subproblems and each one is solved in \(O(m + n)\). So, the time complexity to compute it will be \(O(m \times n \times (m + n))\).
Top-down
from typing import List from functools import cache def solve(m, n, prices): p = {} hs = set() ws = set() for h, w, price in prices: p[(h, w)] = price hs.add(h) ws.add(w) @cache def dfs(h, w): if h == 0 or w == 0: return 0 ans = p.get((h, w), 0) for new_h in range(1, h): if new_h in hs: ans = max(ans, dfs(new_h, w) + dfs(h - new_h, w)) for new_w in range(1, w): if new_w in ws: ans = max(ans, dfs(h, new_w) + dfs(h, w - new_w)) return ans return dfs(m, n) assert solve(3, 5, [[1,4,2],[2,2,7],[2,1,3]]) == 19 assert solve(4, 6, [[3,2,10],[1,4,2],[4,1,3]]) == 32 assert solve(200, 200, [[1,1,1000000]]) == 40000000000 assert solve(15, 7, [[14,3,1],[2,2,1],[15,1,1],[8,1,2],[13,5,1],[6,5,1],[13,1,1],[3,3,2]]) == 25 class Solution: def sellingWood(self, m: int, n: int, prices: List[List[int]]) -> int: return solve(m, n, prices)