Problem Description
Given a rectangle of dimensions n x m, the objective is to cover the entire area using the fewest number of integer-sided squares. The squares may be of different sizes, and they must completely tile the rectangle without overlapping.
Key Insights
- Use recursive backtracking (DFS) to attempt placing a square at the first available empty position.
- Always choose the largest square possible that fits into the remaining space to help reduce the number of tiles.
- Prune paths that already exceed the best solution found so far.
- Because the constraints are small (n, m <= 13), a brute-force DFS with smart ordering and pruning is sufficient.
- Use a grid or bitmask to keep track of the covered area.
Space and Time Complexity
Time Complexity: Exponential in the worst-case, roughly O((nm)!) due to backtracking, but practical due to heavy pruning and small constraints. Space Complexity: O(nm) for the recursion call stack and grid state.
Solution
We solve the problem using a Depth-First Search (DFS) with backtracking. The algorithm iteratively finds the top-left most uncovered cell and attempts to place squares of all possible sizes that fit from that cell. For every square placement, the state of the grid is updated, and the DFS continues recursively to tile the remainder of the rectangle. If the current placement count exceeds the current best solution, the algorithm backtracks. This ensures we explore all possible tilings while pruning inefficient paths.
The main data structures used are:
- A 2D list (grid) to represent the tiling state of the n x m rectangle.
- Recursive stack that holds the current tiling state.
- Variables that track the current count of squares and the minimum number found.
This approach leverages greedy placement combined with recursion. The trick is to always select the next empty cell in a fixed order (top-left priority) and try the largest square possible at that cell, which usually leads to fewer placements overall.