📌  相关文章
📜  通过水平或垂直放置给定的 N 个矩形来最大化上边界的长度

📅  最后修改于: 2021-09-17 06:56:28             🧑  作者: Mango

给定一个成对向量, V[]表示从1N编号的N 个矩形的宽度和高度,这些矩形与水平轴接触放置,并按数字顺序从左到右相邻。任务是找到通过水平或垂直放置每个矩形形成的上边界的最大长度。

红线表示图的上边界

例子:

朴素的方法:最简单的方法是使用递归来尝试通过水平或垂直放置每个矩形来尝试所有可能性。对于每个矩形,有两种选择:水平放置当前矩形或垂直放置当前矩形。打印所有可能性中的最大边界长度。

时间复杂度: O(2 N )
辅助空间: O(1)

高效方法:为了优化上述方法,思想是使用动态规划,因为问题具有重叠子问题和最优子结构属性。每个过渡状态都有 2 个选项:

  1. 水平放置当前过渡状态的矩形
  2. 垂直放置当前过渡状态的矩形

现在,假设矩形被水平放置,然后它在上边界贡献其宽度。现在对于这个矩形,之前的状态矩形要么处于水平位置,要么处于垂直位置。如果前一个矩形处于水平位置或垂直位置,则通过减去两个矩形的边缘来计算当前矩形的左垂直边缘的贡献。

红线表示当前矩形垂直边缘的贡献,黑线表示当前矩形水平边缘在整体边界中的贡献。

如果第i 个矩形是水平放置的,我们定义dp[i][0]为前i矩形的最大上边界,如果第i 个矩形为水平放置,则定义dp[i][1]为前i矩形的最大上边界垂直放置。转换定义为:

请按照以下步骤解决问题:

  • 初始化大小为N*2的二维数组dp[][] 。初始化dp[0][0] = V[0].firstdp[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].firstV[i].first 的绝对差值, vertical2 = V[i-1].firstV[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 现场工作专业课程学生竞争性编程现场课程