给定一个成对向量, V[]表示从1到N编号的N 个矩形的宽度和高度,这些矩形与水平轴接触放置,并按数字顺序从左到右相邻。任务是找到通过水平或垂直放置每个矩形形成的上边界的最大长度。
例子:
Input: N = 5, V[] = {{2, 5}, {3, 8}, {1, 10}, {7, 14}, {2, 5}}
Output: 68
Explanation: Place the first and the third rectangle vertically and all the other rectangles horizontally to get the maximum length of the upper boundary. (5 + 6 + 3 + 7 + 10 + 13 + 7 + 12 + 5 = 68)
Input: N = 1, V[] = {{8, 7}}
Output: 8
Explanation: Place the only rectangle horizontally, so that the length of the upper boundary becomes 8.
朴素的方法:最简单的方法是使用递归来尝试通过水平或垂直放置每个矩形来尝试所有可能性。对于每个矩形,有两种选择:水平放置当前矩形或垂直放置当前矩形。打印所有可能性中的最大边界长度。
时间复杂度: O(2 N )
辅助空间: O(1)
高效方法:为了优化上述方法,思想是使用动态规划,因为问题具有重叠子问题和最优子结构属性。每个过渡状态都有 2 个选项:
- 水平放置当前过渡状态的矩形
- 垂直放置当前过渡状态的矩形
现在,假设矩形被水平放置,然后它在上边界贡献其宽度。现在对于这个矩形,之前的状态矩形要么处于水平位置,要么处于垂直位置。如果前一个矩形处于水平位置或垂直位置,则通过减去两个矩形的边缘来计算当前矩形的左垂直边缘的贡献。
如果第i 个矩形是水平放置的,我们定义dp[i][0]为前i个矩形的最大上边界,如果第i 个矩形为水平放置,则定义dp[i][1]为前i个矩形的最大上边界垂直放置。转换定义为:
Let height1= |V[i – 1].second – V[i].second| and height2 = |V[i – 1].first – V[i].second|
Then, dp[i][0]= max(height1+dp[i-1][0], height2+dp[i-1][1])+V[i].first
Let vertical1 = |V[i].first – V[i -1].second| and vertical2 = | V[i].first – V[i – 1].first|
then dp[i][1] = max(vertical1 + dp[i-1][0], vertical2 + dp[i-1][1]) + V[i].second
请按照以下步骤解决问题:
- 初始化大小为N*2的二维数组dp[][] 。初始化dp[0][0] = V[0].first和dp[0][1] = V[0].second 。
- 使用变量i遍历范围[1, N]并按照以下步骤操作:
- 初始化变量height1 = V的绝对差[I-1]。第二和V [I]。第二和身高2 = V的绝对差[I-1]。首先和V [I]。第二。同时将dp[i][0]的值更新为V[i].first 。
- 将max(dp[i-1][0]+height1, dp[i-1][1]+height2) 添加到dp[i][0] 的值。
- 将dp[i][1]初始化为V[i].second 。还要初始化变量vertical1 = V[i-1].first和V[i].first 的绝对差值, vertical2 = V[i-1].first和V[i].first 的绝对差值。
- 将max(dp[i-1][0]+vertical1, dp[i-1][1]+vertical2) 添加到dp[i][1] 的值。
- 完成上述步骤后,打印max(dp[N-1][0], dp[N-1][1]) 的值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find maximum length of the upper
// boundary formed by placing each of the
// rectangles either horizontally or vertically
void maxBoundary(int N, vector > V)
{
// Stores the intermediate
// transition states
int dp[N][2];
memset(dp, 0, sizeof(dp));
// Place the first rectangle
// horizontally
dp[0][0] = V[0].first;
// Place the first rectangle
// vertically
dp[0][1] = V[0].second;
for (int i = 1; i < N; i++) {
// Place horizontally
dp[i][0] = V[i].first;
// Stores the difference in height of
// current and previous rectangle
int height1 = abs(V[i - 1].second - V[i].second);
int height2 = abs(V[i - 1].first - V[i].second);
// Take maximum out of two options
dp[i][0] += max(height1 + dp[i - 1][0],
height2 + dp[i - 1][1]);
// Place Vertically
dp[i][1] = V[i].second;
// Stores the difference in height of
// current and previous rectangle
int vertical1 = abs(V[i].first - V[i - 1].second);
int vertical2 = abs(V[i].first - V[i - 1].first);
// Take maximum out two options
dp[i][1] += max(vertical1 + dp[i - 1][0],
vertical2 + dp[i - 1][1]);
}
// Print maximum of horizontal or vertical
// alignment of the last rectangle
cout << max(dp[N - 1][0], dp[N - 1][1]);
}
// Driver Code
int main()
{
int N = 5;
vector > V
= { { 2, 5 }, { 3, 8 }, { 1, 10 }, { 7, 14 }, { 2, 5 } };
maxBoundary(N, V);
return 0;
}
Java
// Java program for the above approach
import java.util.Vector;
public class GFG {
public static class pair {
private int first;
private int second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Function to find maximum length of the upper
// boundary formed by placing each of the
// rectangles either horizontally or vertically
static void maxBoundary(int N, Vector V)
{
// Stores the intermediate
// transition states
int dp[][] = new int[N][2];
// Place the first rectangle
// horizontally
dp[0][0] = V.get(0).first;
// Place the first rectangle
// vertically
dp[0][1] = V.get(0).second;
for (int i = 1; i < N; i++) {
// Place horizontally
dp[i][0] = V.get(i).first;
// Stores the difference in height of
// current and previous rectangle
int height1 = Math.abs(V.get(i - 1).second
- V.get(i).second);
int height2 = Math.abs(V.get(i - 1).first
- V.get(i).second);
// Take maximum out of two options
dp[i][0] += Math.max(height1 + dp[i - 1][0],
height2 + dp[i - 1][1]);
// Place Vertically
dp[i][1] = V.get(i).second;
// Stores the difference in height of
// current and previous rectangle
int vertical1 = Math.abs(V.get(i).first
- V.get(i - 1).second);
int vertical2 = Math.abs(V.get(i).first
- V.get(i - 1).first);
// Take maximum out two options
dp[i][1] += Math.max(vertical1 + dp[i - 1][0],
vertical2 + dp[i - 1][1]);
}
// Print maximum of horizontal or vertical
// alignment of the last rectangle
System.out.println(
Math.max(dp[N - 1][0], dp[N - 1][1]));
}
// Driver code
public static void main(String[] args)
{
int N = 5;
Vector V = new Vector<>();
V.add(new pair(2, 5));
V.add(new pair(3, 8));
V.add(new pair(1, 10));
V.add(new pair(7, 14));
V.add(new pair(2, 5));
maxBoundary(N, V);
}
}
// This code is contributed by abhinavjain194
Python3
# Python 3 program for the above approach
# Function to find maximum length of the upper
# boundary formed by placing each of the
# rectangles either horizontally or vertically
def maxBoundary(N, V):
# Stores the intermediate
# transition states
dp = [[0 for i in range(2)] for j in range(N)]
# Place the first rectangle
# horizontally
dp[0][0] = V[0][0]
# Place the first rectangle
# vertically
dp[0][1] = V[0][1]
for i in range(1, N, 1):
# Place horizontally
dp[i][0] = V[i][0]
# Stores the difference in height of
# current and previous rectangle
height1 = abs(V[i - 1][1] - V[i][1])
height2 = abs(V[i - 1][0] - V[i][1])
# Take maximum out of two options
dp[i][0] += max(height1 + dp[i - 1][0], height2 + dp[i - 1][1])
# Place Vertically
dp[i][1] = V[i][1]
# Stores the difference in height of
# current and previous rectangle
vertical1 = abs(V[i][0] - V[i - 1][1]);
vertical2 = abs(V[i][0] - V[i - 1][1]);
# Take maximum out two options
dp[i][1] += max(vertical1 + dp[i - 1][0], vertical2 + dp[i - 1][1])
# Print maximum of horizontal or vertical
# alignment of the last rectangle
print(max(dp[N - 1][0], dp[N - 1][1])-1)
# Driver Code
if __name__ == '__main__':
N = 5
V = [[2, 5],[3, 8],[1, 10],[7, 14],[2, 5]]
maxBoundary(N, V)
# This code is contributed by SURENDRA_GANGWAR.
Javascript
68
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。