Skip to content
Related Articles

Related Articles

Improve Article
Largest subset of rectangles such that no rectangle fit in any other rectangle
  • Difficulty Level : Expert
  • Last Updated : 15 Jun, 2021

Given height and width of N rectangles. The task is to find the size of the largest subset such that no pair of rectangles fit within each other. Note that if H1 ≤ H2 and W1 ≤ W2 then rectangle 1 fits inside rectangle 2. 
Examples: 
 

Input: arr[] = {{1, 3}, {2, 2}, {1, 3}} 
Output:
The required sub-set is {{1, 3}, {2, 2}} 
{1, 3} is included only once as it can fit in {1, 3}
Input: arr[] = {{1, 5}, {2, 4}, {1, 1}, {3, 3}} 
Output:
 

 

Approach: The above problem can be solved using Dynamic Programming and sorting. Initially, we can sort the N pairs on the basis of heights. A recursive function can be written where there will be two states.
The first state being, if the present rectangle does not fit in the previous rectangle or the vice versa, then we call for the next state with the present rectangle being the previous rectangle and moving to the next rectangle. 
 

dp[present][previous] = max(dp[present][previous], 1 + dp[present + 1][present]) 
 



If it does fit in, we call the next state with the previous rectangle and moving to the next rectangle. 
 

dp[present][previous] = max(dp[present][previous], dp[present + 1][previous]) 
 

Memoization can be further used to avoid repetitively the same states being called. 
Below is the implementation of the above approach:
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define N 10
int dp[N][N];
 
// Recursive function to get the largest subset
int findLongest(pair<int, int> a[], int n,
                int present, int previous)
{
    // Base case when it exceeds
    if (present == n) {
        return 0;
    }
 
    // If the state has been visited previously
    else if (previous != -1) {
        if (dp[present][previous] != -1)
            return dp[present][previous];
    }
 
    // Initialize
    int ans = 0;
 
    // No elements in subset yet
    if (previous == -1) {
 
        // First state which includes current index
        ans = 1 + findLongest(a, n,
                              present + 1, present);
 
        // Second state which does not include current index
        ans = max(ans, findLongest(a, n,
                                   present + 1, previous));
    }
    else {
        int h1 = a[previous].first;
        int h2 = a[present].first;
        int w1 = a[previous].second;
        int w2 = a[present].second;
 
        // If the rectangle fits in, then do not include
        // the current index in subset
        if ((h1 <= h2 && w1 <= w2)) {
            ans = max(ans, findLongest(a, n,
                                       present + 1, previous));
        }
        else {
 
            // First state which includes current index
            ans = 1 + findLongest(a, n,
                                  present + 1, present);
 
            // Second state which does not include current index
            ans = max(ans, findLongest(a, n,
                                       present + 1, previous));
        }
    }
 
    return dp[present][previous] = ans;
}
 
// Function to get the largest subset
int getLongest(pair<int, int> a[], int n)
{
    // Initialize the DP table with -1
    memset(dp, -1, sizeof dp);
 
    // Sort the array
    sort(a, a + n);
 
    // Get the answer
    int ans = findLongest(a, n, 0, -1);
    return ans;
}
 
// Driver code
int main()
{
 
    // (height, width) pairs
    pair<int, int> a[] = { { 1, 5 },
                           { 2, 4 },
                           { 1, 1 },
                           { 3, 3 } };
    int n = sizeof(a) / sizeof(a[0]);
 
    cout << getLongest(a, n);
 
    return 0;
}

Python3




# Python3 implementation of the approach
 
# Recursive function to get the
# largest subset
def findLongest(a, n, present, previous):
 
    # Base case when it exceeds
    if present == n:
        return 0
     
    # If the state has been visited
    # previously
    elif previous != -1:
        if dp[present][previous] != -1:
            return dp[present][previous]
 
    # Initialize
    ans = 0
 
    # No elements in subset yet
    if previous == -1:
 
        # First state which includes
        # current index
        ans = 1 + findLongest(a, n, present + 1,
                                    present)
 
        # Second state which does not
        # include current index
        ans = max(ans, findLongest(a, n, present + 1,
                                         previous))
     
    else:
        h1 = a[previous][0]
        h2 = a[present][0]
        w1 = a[previous][1]
        w2 = a[present][1]
 
        # If the rectangle fits in, then do
        # not include the current index in subset
        if h1 <= h2 and w1 <= w2:
            ans = max(ans, findLongest(a, n, present + 1,
                                             previous))
         
        else:
 
            # First state which includes
            # current index
            ans = 1 + findLongest(a, n, present + 1,
                                        present)
 
            # Second state which does not
            # include current index
            ans = max(ans, findLongest(a, n, present + 1,
                                             previous))
 
    dp[present][previous] = ans
    return ans
 
# Function to get the largest subset
def getLongest(a, n):
 
    # Sort the array
    a.sort()
 
    # Get the answer
    ans = findLongest(a, n, 0, -1)
    return ans
 
# Driver code
if __name__ == "__main__":
 
    # (height, width) pairs
    a = [[1, 5], [2, 4], [1, 1], [3, 3]]
     
    N = 10
     
    # Initialize the DP table with -1
    dp = [[-1 for i in range(N)]
              for j in range(N)]
 
    n = len(a)
    print(getLongest(a, n))
 
# This code is contributed
# by Rituraj Jain

Javascript




<script>
 
// JavaScript implementation of the approach
var N = 10;
var dp = Array.from(Array(N), ()=>Array(N).fill(-1));
 
// Recursive function to get the largest subset
function findLongest(a, n, present, previous)
{
    // Base case when it exceeds
    if (present == n) {
        return 0;
    }
 
    // If the state has been visited previously
    else if (previous != -1) {
        if (dp[present][previous] != -1)
            return dp[present][previous];
    }
 
    // Initialize
    var ans = 0;
 
    // No elements in subset yet
    if (previous == -1) {
 
        // First state which includes current index
        ans = 1 + findLongest(a, n,
                              present + 1, present);
 
        // Second state which does not include current index
        ans = Math.max(ans, findLongest(a, n,
                                   present + 1, previous));
    }
    else {
        var h1 = a[previous][0];
        var h2 = a[present][0];
        var w1 = a[previous][1];
        var w2 = a[present][1];
 
        // If the rectangle fits in, then do not include
        // the current index in subset
        if ((h1 <= h2 && w1 <= w2)) {
            ans = Math.max(ans, findLongest(a, n,
                                       present + 1, previous));
        }
        else {
 
            // First state which includes current index
            ans = 1 + findLongest(a, n,
                                  present + 1, present);
 
            // Second state which does not include current index
            ans = Math.max(ans, findLongest(a, n,
                                       present + 1, previous));
        }
    }
 
    return dp[present][previous] = ans;
}
 
// Function to get the largest subset
function getLongest(a, n)
{
    // Initialize the DP table with -1
    dp = Array.from(Array(N), ()=>Array(N).fill(-1));
 
    // Sort the array
    a.sort((a,b)=>a-b);
 
    // Get the answer
    var ans = findLongest(a, n, 0, -1);
    return ans;
}
 
// Driver code
// (height, width) pairs
var a = [ [ 1, 5 ],
          [ 2, 4 ],
          [ 1, 1 ],
          [ 3, 3 ] ];
var n = a.length;
document.write( getLongest(a, n));
 
 
</script>
Output: 
3

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live




My Personal Notes arrow_drop_up
Recommended Articles
Page :