📌  相关文章
📜  找到一个插入另一个矩形后剩余的最小矩形数

📅  最后修改于: 2021-05-06 20:52:56             🧑  作者: Mango

给定N个矩形的宽度高度。任务是找到将一个矩形插入另一个矩形后剩余的最小矩形数。

笔记 :

  1. 如果W1
  2. 最小的矩形可以插入第二个最小的矩形,而这个矩形可以插入下一个最小的矩形,依此类推。

例子:

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.

方法

  1. 首先对所有矩形进行排序,以使高度按降序排列。我们将首先假定每个高度都是唯一的(稍后,我们将把方法扩展到具有相同高度的情况)。
  2. 我们维护另一个嵌套的数组[i]。从最高的矩形到最短的矩形,我们将尝试在nested [i]中找到一个嵌套的矩形,使其嵌套[i],该嵌套的矩形的宽度大于当前矩形的宽度。不仅如此,我们还希望将其放置在宽度最小的那一个中。然后,我们将矩形放置在该嵌套矩形内,并更新其新的高度和权重。为什么最少的一个?因为如果将矩形放置在另一个宽度大于最小宽度的矩形上,则可以应用以下交换参数:
    假设存在一个最佳布置,使得当前的矩形[i]不会放在满足上述要求的最小宽度的嵌套[m]上。假设矩形[i]放在nested [n]上,而另一个矩形[j]放在nested [m]上。然后,因为矩形[j]可以适合nested [n],所以它也可以适合nested [m],因此我们可以交换矩形[i]和矩形[j]。通过在所有阶段对所有此类矩形执行交换,我们可以将这种最佳排列转换为贪婪排列。因此,我们的贪心安排也是最优的。
  3. 归纳地,我们可以证明nested [i]中的矩形总是以递增的宽度排序。
  4. 最后,在存在一个具有相同高度的矩形的情况下,我们以递增顺序对宽度进行排序,以保持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