สมมติว่าเรามีสี่เหลี่ยมจัตุรัสขนาด n x m เราต้องหาจำนวนขั้นต่ำของวัตถุสี่เหลี่ยมจัตุรัสด้านจำนวนเต็มที่สามารถเรียงต่อกันสี่เหลี่ยมได้
ดังนั้น หากอินพุตเป็น n =2 และ m =3

จากนั้นผลลัพธ์จะเป็น 3 เนื่องจากเราต้องการสามช่วงตึก
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดหนึ่งแผนที่ m
-
res :=inf
-
กำหนดฟังก์ชัน dfs() ซึ่งจะใช้เวลา n, m, อาร์เรย์ h, cnt,
-
ถ้า cnt>=res แล้ว −
-
กลับ
-
-
isFull :=จริง
-
pos :=-1, minH :=inf
-
สำหรับการเริ่มต้น i :=1 เมื่อฉัน <=n อัปเดต (เพิ่ม i ขึ้น 1) ทำ -
-
ถ้า h[i]
-
isFull :=เท็จ
-
-
ถ้า h[i]
-
minH :=h[i]
-
pos :=ฉัน
-
-
-
ถ้า isFull ไม่ใช่ศูนย์ ดังนั้น −
-
res :=ขั้นต่ำของ res และ cnt
-
กลับ
-
-
คีย์ :=0
-
ฐาน :=m + 1
-
สำหรับการเริ่มต้น i :=1 เมื่อฉัน <=n อัปเดต (เพิ่ม i ขึ้น 1) ทำ -
-
คีย์ :=คีย์ + h[i] * ฐาน
-
ฐาน :=ฐาน * (m + 1)
-
-
ถ้าคีย์อยู่ใน s และ s[key] <=cnt แล้ว −
-
กลับ
-
-
s[คีย์] :=cnt
-
จบ :=pos
-
ในขณะที่ (end + 1 <=n และ h[end + 1] เหมือนกับ h[pos] และ (end + 1 - pos + 1 + minH)
-
<=m) ทำ −
-
(เพิ่มขึ้นท้าย 1)
-
-
สำหรับการเริ่มต้น j :=end เมื่อ j>=pos อัปเดต (ลด j โดย 1) ทำ -
-
curH :=j - pos + 1
-
กำหนดอาร์เรย์ถัดไปของขนาด n + 1
-
สำหรับการเริ่มต้น i :=1 เมื่อฉัน <=n อัปเดต (เพิ่ม i ขึ้น 1) ทำ -
-
ต่อไป[i] :=h[i]
-
-
สำหรับการเริ่มต้น k :=pos เมื่อ k <=j อัปเดต (เพิ่ม k ขึ้น 1) ทำ -
-
next[k] :=next[k] + curH
-
-
dfs(n, m, ถัดไป, cnt + 1)
-
-
จากวิธีหลัก ให้ทำดังต่อไปนี้ −
-
ถ้า n เท่ากับ m แล้ว −
-
กลับ 1
-
-
ถ้า n> m แล้ว
-
สลับ(n, m)
-
-
กำหนดอาร์เรย์ h ขนาด n + 1
-
dfs(n, m, h, 0)
-
ผลตอบแทน
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#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));
} อินพุต
2,3
ผลลัพธ์
3