Subconjunto más grande de rectángulos tal que ningún rectángulo cabe en ningún otro rectángulo

Dada la altura y el ancho de N rectángulos. La tarea es encontrar el tamaño del subconjunto más grande de manera que ningún par de rectángulos encajen entre sí. Tenga en cuenta que si H1 ≤ H2 y W1 ≤ W2 , entonces el rectángulo 1 cabe dentro del rectángulo 2. 
Ejemplos: 
 

Entrada: arr[] = {{1, 3}, {2, 2}, {1, 3}} 
Salida:
El subconjunto requerido es {{1, 3}, {2, 2}} 
{1, 3} se incluye solo una vez, ya que puede caber en {1, 3}
Entrada: arr[] = {{1, 5}, {2, 4}, {1, 1}, {3, 3}} Salida 
:
 

Enfoque: el problema anterior se puede resolver utilizando la programación dinámica y la clasificación . Inicialmente, podemos clasificar los N pares en función de las alturas. Se puede escribir una función recursiva donde habrá dos estados.
El primer estado es, si el rectángulo actual no encaja en el rectángulo anterior o viceversa, entonces llamamos al siguiente estado con el rectángulo actual siendo el rectángulo anterior y moviéndose al siguiente rectángulo. 
 

dp[presente][anterior] = max(dp[presente][anterior], 1 + dp[presente + 1][presente]) 
 

Si encaja, llamamos al siguiente estado con el rectángulo anterior y pasamos al siguiente rectángulo. 
 

dp[presente][anterior] = max(dp[presente][anterior], dp[presente + 1][anterior]) 
 

La memorización se puede utilizar además para evitar que se llamen repetitivamente a los mismos estados. 
A continuación se muestra la implementación del enfoque anterior:
 

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;
}

Java

// Java implementation of the above approach.
import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
 
public class GFG {
 
    // A function to sort the 2D array by column number.
    static void Sort(int[][] array, final int columnNumber)
    {
        Arrays.sort(array, new Comparator<int[]>() {
            @Override
            public int compare(int[] first, int[] second)
            {
                if (columnNumber >= 1
                    && first[columnNumber - 1]
                           > second[columnNumber - 1])
                    return 1;
                else
                    return -1;
            }
        });
    }
 
    // Recursive function to get the largest subset
    static int findLongest(int[][] a, int n, int present,
                           int previous, int[][] dp, int N)
    {
        // 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,
                                dp, N);
 
            // Second state which does not include current
            // index
            ans = Math.max(ans,
                           findLongest(a, n, present + 1,
                                       previous, dp, N));
        }
        else {
            int h1 = a[previous][0];
            int h2 = a[present][0];
            int w1 = a[previous][1];
            int 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, dp, N));
            }
            else {
 
                // First state which includes current index
                ans = 1
                      + findLongest(a, n, present + 1,
                                    present, dp, N);
 
                // Second state which does not include
                // current index
                ans = Math.max(
                    ans, findLongest(a, n, present + 1,
                                     previous, dp, N));
            }
        }
 
        if (present >= 0 && previous >= 0) {
            return dp[present][previous] = ans;
        }
        return ans;
    }
 
    // Function to get the largest subset
    static int getLongest(int[][] a, int n)
    {
        int N = 10;
        int[][] dp = new int[N + 1][N + 1];
        // Initialize the DP table with -1
        for (int i = 0; i < N + 1; i++) {
            for (int j = 0; j < N + 1; j++) {
                dp[i][j] = -1;
            }
        }
 
        // Sort the array
        Sort(a, 0);
 
        // Get the answer
        int ans = findLongest(a, n, 0, -1, dp, N);
        return ans;
    }
 
    // Driver code
    // (height, width) pairs
    public static void main(String[] args)
    {
        int[][] a
            = { { 1, 5 }, { 2, 4 }, { 1, 1 }, { 3, 3 } };
        int n = a.length;
        System.out.println(getLongest(a, n));
    }
}
 
  // The code is contributed by Gautam goel (guatamgoel962)

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>
Producción: 

3

 

Complejidad de tiempo: O(N*N), donde las operaciones dp toman N*N tiempo 
Espacio auxiliar: O(N*N), array dp formada por dos estados, cada uno con N espacio, es decir, N*N

Publicación traducida automáticamente

Artículo escrito por Striver y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *