考虑一个二维地图,其中一条水平河流穿过其中心。南岸有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问题的变体。以下是解决问题的步骤。
- 根据南x坐标的升序对南北对进行排序。
- 如果两个南x坐标相同,则根据北x坐标的升序进行排序。
- 现在找到北x坐标的最长递增子序列。
- 要注意的一件事是,在增加的子序列中,值可以更大,也可以等于其先前的值。
我们还可以根据北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