给定N 个矩形的高度和宽度。任务是找到最大子集的大小,使得没有一对矩形彼此适合。请注意,如果H1 ≤ H2且W1 ≤ W2,则矩形 1 适合矩形 2。
例子:
Input: arr[] = {{1, 3}, {2, 2}, {1, 3}}
Output: 2
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: 3
方法:上述问题可以使用动态规划和排序来解决。最初,我们可以根据高度对 N 对进行排序。递归函数可以写成有两种状态。
第一个状态是,如果当前矩形不适合前一个矩形,反之亦然,那么我们调用下一个状态,当前矩形是前一个矩形并移动到下一个矩形。
dp[present][previous] = max(dp[present][previous], 1 + dp[present + 1][present])
如果它适合,我们用前一个矩形调用下一个状态并移动到下一个矩形。
dp[present][previous] = max(dp[present][previous], dp[present + 1][previous])
可以进一步使用记忆化来避免重复调用相同的状态。
下面是上述方法的实现:
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