-
Notifications
You must be signed in to change notification settings - Fork 0
/
1240. Tiling a Rectangle with the Fewest Squares
45 lines (39 loc) · 1.42 KB
/
1240. Tiling a Rectangle with the Fewest Squares
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Solution {
public:
int tilingRectangle(int n, int m) {
unordered_map<long, int> mem;
return tilingRectangle(n, m, 0, /*heights=*/vector<int>(m), mem);
}
private:
static constexpr int kBase = 13;
int tilingRectangle(int n, int m, long hashedHeights, vector<int>&& heights,
unordered_map<long, int>& mem) {
if (const auto it = mem.find(hashedHeights); it != mem.cend())
return it->second;
const auto it = ranges::min_element(heights);
const int minHeight = *it;
if (minHeight == n) // All filled.
return 0;
int ans = m * n;
const int start = it - heights.begin();
// Try to put square of different size that doesn't exceed the width/height.
for (int sz = 1; sz <= min(m - start, n - minHeight); ++sz) {
// heights[start..start + sz) must has the same height.
if (heights[start + sz - 1] != minHeight)
break;
// Put a square of size `sz` to cover heights[start..start + sz).
for (int i = start; i < start + sz; ++i)
heights[i] += sz;
ans = min(ans, tilingRectangle(n, m, hash(heights), move(heights), mem));
for (int i = start; i < start + sz; ++i)
heights[i] -= sz;
}
return mem[hashedHeights] = 1 + ans;
}
long hash(const vector<int>& heights) {
long hashed = 0;
for (int i = heights.size() - 1; i >= 0; --i)
hashed = hashed * kBase + heights[i];
return hashed;
}
};