📜  矩形的最大子集,使得没有矩形适合任何其他矩形

📅  最后修改于: 2021-09-22 10:10:57             🧑  作者: Mango

给定N 个矩形的高度宽度。任务是找到最大子集的大小,使得没有一对矩形彼此适合。请注意,如果H1 ≤ H2W1 ≤ W2,则矩形 1 适合矩形 2。
例子:

方法:上述问题可以使用动态规划和排序来解决。最初,我们可以根据高度对 N 对进行排序。递归函数可以写成有两种状态。
第一个状态是,如果当前矩形不适合前一个矩形,反之亦然,那么我们调用下一个状态,当前矩形是前一个矩形并移动到下一个矩形。

如果它适合,我们用前一个矩形调用下一个状态并移动到下一个矩形。

可以进一步使用记忆化来避免重复调用相同的状态。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define N 10
int dp[N][N];
 
// Recursive function to get the largest subset
int findLongest(pair 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 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 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


输出:
3