Giả sử chúng ta có một hình chữ nhật kích thước n x m. Chúng ta phải tìm số lượng tối thiểu các đối tượng hình vuông cạnh các số nguyên có thể xếp các hình chữ nhật.
Vì vậy, nếu đầu vào là n =2 và m =3,
thì đầu ra sẽ là 3, vì chúng ta cần ba khối.
Để giải quyết vấn đề này, chúng tôi sẽ làm theo các bước sau -
-
Xác định một bản đồ m
-
res:=inf
-
Xác định một hàm dfs (), hàm này sẽ lấy n, m, một mảng h, cnt,
-
nếu cnt> =res, thì -
-
trở lại
-
-
isFull:=true
-
pos:=-1, minH:=inf
-
để khởi tạo i:=1, khi i <=n, cập nhật (tăng i lên 1), thực hiện -
-
nếu h [i]
-
isFull:=false
-
-
nếu h [i]
-
minH:=h [i]
-
pos:=i
-
-
-
nếu isFull khác 0, thì -
-
res:=tối thiểu res và cnt
-
trở lại
-
-
khóa:=0
-
cơ sở:=m + 1
-
để khởi tạo i:=1, khi i <=n, cập nhật (tăng i lên 1), thực hiện -
-
key:=key + h [i] * base
-
cơ sở:=cơ sở * (m + 1)
-
-
nếu khóa bằng s và s [key] <=cnt, thì -
-
trở lại
-
-
s [key]:=cnt
-
end:=pos
-
while (end + 1 <=n và h [end + 1] giống với h [pos] và (end + 1 - pos + 1 + minH)
-
<=m), làm -
-
(tăng cuối cùng lên 1)
-
-
để khởi tạo j:=end, khi j> =pos, update (giảm j đi 1), do -
-
curH:=j - pos + 1
-
Xác định một mảng tiếp theo có kích thước n + 1
-
để khởi tạo i:=1, khi i <=n, cập nhật (tăng i lên 1), thực hiện -
-
tiếp theo [i]:=h [i]
-
-
để khởi tạo k:=pos, khi k <=j, cập nhật (tăng k lên 1), thực hiện -
-
tiếp theo [k]:=tiếp theo [k] + curH
-
-
dfs (n, m, tiếp theo, cnt + 1)
-
-
Từ phương thức chính, thực hiện như sau -
-
nếu n giống với m thì -
-
trả lại 1
-
-
nếu n> m thì
-
hoán đổi (n, m)
-
-
Xác định một mảng h có kích thước n + 1
-
dfs (n, m, h, 0)
-
trả lại res
Hãy cùng chúng tôi xem cách triển khai sau để hiểu rõ hơn -
Ví dụ
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
map<int, int> s;
int res = INT_MAX;
void dfs(int n, int m, vector<int> h, int cnt){
if (cnt >= res)
return;
bool isFull = true;
int pos = -1, minH = INT_MAX;
for (int i = 1; i <= n; i++) {
if (h[i] < m)
isFull = false;
if (h[i] < minH) {
minH = h[i];
pos = i;
}
}
if (isFull) {
res = min(res, cnt);
return;
}
long key = 0;
long base = m + 1;
for (int i = 1; i <= n; i++) {
key += h[i] * base;
base *= m + 1;
}
if (s.find(key) != s.end() && s[key] <= cnt)
return;
s[key] = cnt;
int end = pos;
while (end + 1 <= n && h[end + 1] == h[pos] && (end + 1 - pos + 1 + minH) <= m)
end++;
for (int j = end; j >= pos; j--) {
int curH = j - pos + 1;
vector<int> next(n + 1);
for (int i = 1; i <= n; i++)
next[i] = h[i];
for (int k = pos; k <= j; k++) {
next[k] += curH;
}
dfs(n, m, next, cnt + 1);
}
}
int tilingRectangle(int n, int m){
if (n == m)
return 1;
if (n > m)
swap(n, m);
vector<int> h(n + 1);
dfs(n, m, h, 0);
return res;
}
};
main(){
Solution ob;
cout << (ob.tilingRectangle(2, 3));
} Đầu vào
2,3
Đầu ra
3