给定N个矩形的宽度和高度。任务是找到将一个矩形插入另一个矩形后剩余的最小矩形数。
笔记 :
- 如果W1
- 最小的矩形可以插入第二个最小的矩形,而这个矩形可以插入下一个最小的矩形,依此类推。
例子:
Input : arr[] = {{20, 30}, {10, 10}, {30, 20}, {40, 50}};
Output : 2
Explanation : One of the possible way is to insert
second recatngle in first and then insert
first rectangle in fourth.
Then finally, third and fourth rectangles left.
Input : arr[] = {{10, 30}, {20, 20}, {30, 10}};
Output : 3
Explanation : Can't place any rectangle in any other one.
So, three rectangles left.
方法:
- 首先对所有矩形进行排序,以使高度按降序排列。我们将首先假定每个高度都是唯一的(稍后,我们将把方法扩展到具有相同高度的情况)。
- 我们维护另一个嵌套的数组[i]。从最高的矩形到最短的矩形,我们将尝试在nested [i]中找到一个嵌套的矩形,使其嵌套[i],该嵌套的矩形的宽度大于当前矩形的宽度。不仅如此,我们还希望将其放置在宽度最小的那一个中。然后,我们将矩形放置在该嵌套矩形内,并更新其新的高度和权重。为什么最少的一个?因为如果将矩形放置在另一个宽度大于最小宽度的矩形上,则可以应用以下交换参数:
假设存在一个最佳布置,使得当前的矩形[i]不会放在满足上述要求的最小宽度的嵌套[m]上。假设矩形[i]放在nested [n]上,而另一个矩形[j]放在nested [m]上。然后,因为矩形[j]可以适合nested [n],所以它也可以适合nested [m],因此我们可以交换矩形[i]和矩形[j]。通过在所有阶段对所有此类矩形执行交换,我们可以将这种最佳排列转换为贪婪排列。因此,我们的贪心安排也是最优的。 - 归纳地,我们可以证明nested [i]中的矩形总是以递增的宽度排序。
- 最后,在存在一个具有相同高度的矩形的情况下,我们以递增顺序对宽度进行排序,以保持nested [i]的排序顺序。
下面是上述方法的实现:
// CPP program to find the minimum number of rectangles
// left after inserting one into another
#include
using namespace std;
// Function for comparison
bool comp(const pair& L, const pair& R)
{
if (L.first == R.first)
return L.second > R.second;
return L.first < R.first;
}
// Function to find the minimum number of rectangles
// left after inserting one into another
int Rectangles(pair rectangle[], int n)
{
// Sort rectangles in increasing order of width
// and decreasing order of height
sort(rectangle, rectangle + n, comp);
vector > nested;
// Keep the largest rectangle
nested.push_back(rectangle[n - 1]);
// For all remaining rectangles
for (int i = n - 2; i >= 0; --i) {
int high = nested.size() - 1, low = 0;
// Fidn the position of this rectangle in nested
while (low <= high) {
int mid = (high + low) / 2;
if (nested[mid].first == rectangle[i].first
|| nested[mid].second <= rectangle[i].second)
low = mid + 1;
else
high = mid - 1;
}
// If this rectangle not possible to insert in
// any other rectangle
if (low == nested.size())
nested.push_back(rectangle[i]);
// Replace with previous rectangle
else {
nested[low].second = rectangle[i].second;
nested[low].first = rectangle[i].first;
}
}
return ((int)nested.size());
}
// Driver code
int main()
{
// list of Width, Height pair
pair arr[] = { { 20, 30 }, { 10, 10 }, { 30, 20 }, { 40, 50 } };
int n = sizeof(arr) / sizeof(arr[0]);
cout << Rectangles(arr, n);
return 0;
}
输出:
2