📜  动态编程|建筑桥梁

📅  最后修改于: 2021-05-04 10:24:26             🧑  作者: Mango

考虑一个二维地图,其中一条水平河流穿过其中心。南岸有n个城市的x坐标为a(1)…a(n),北岸有n个城市的x坐标为b(1)…b(n)。您希望通过桥梁连接尽可能多的南北对城市,这样就不会有两座桥梁交叉。连接城市时,只能将北岸的城市a(i)连接到南岸的城市b(i)。可以建立连接上述约束的南北对桥梁的最大数量。

空值

上银行中的值可以视为城市的北部x坐标,下银行中的值可以视为可以与北部x坐标城市连接的城市的相应南部x坐标。

例子:

Input : 6 4 2 1
        2 3 6 5
Output : Maximum number of bridges = 2
Explanation: Let the north-south x-coordinates
be written in increasing order.

1  2  3  4  5  6
  \  \
   \  \        For the north-south pairs
    \  \       (2, 6) and (1, 5)
     \  \      the bridges can be built.
      \  \     We can consider other pairs also,
       \  \    but then only one bridge can be built 
        \  \   because more than one bridge built will
         \  \  then cross each other.
          \  \
1  2  3  4  5  6 

Input : 8 1 4 3 5 2 6 7 
        1 2 3 4 5 6 7 8
Output : Maximum number of bridges = 5

方法:这是LIS问题的变体。以下是解决问题的步骤。

  1. 根据南x坐标的升序对南北对进行排序。
  2. 如果两个南x坐标相同,则根据北x坐标的升序进行排序。
  3. 现在找到北x坐标的最长递增子序列。
  4. 要注意的一件事是,在增加的子序列中,值可以更大,也可以等于其先前的值。

我们还可以根据北x坐标进行排序,并在南x坐标上找到LIS。

// C++ implementation of building bridges
#include 
  
using namespace std;
  
// north-south coodinates
// of each City Pair
struct CityPairs
{
    int north, south;
};
  
// comparison function to sort
// the given set of CityPairs
bool compare(struct CityPairs a, struct CityPairs b)
{
    if (a.south == b.south)
        return a.north < b.north;
    return a.south < b.south;
}
  
// function to find the maximum number
// of bridges that can be built
int maxBridges(struct CityPairs values[], int n)
{
    int lis[n];
    for (int i=0; i= values[j].north 
                && lis[i] < 1 + lis[j])
                lis[i] = 1 + lis[j];
          
          
    int max = lis[0];
    for (int i=1; i
Maximum number of bridges = 2

时间复杂度:O(n 2 )

问题参考:
https://www.geeksforgeeks.org/dynamic-programming-set-14-variations-of-lis/

解决方案参考:
https://www.youtube.com/watch?v=w6tSmS86C4w