友好城市(LIS)

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例

7
22 4
2 6
10 3
15 12
9 8
17 17
4 2

输出样例

4

数据范围

在这里插入图片描述


题目大意: 上下两端有一一对应的两个点,其中每一对之间可以产生一条连线。问在所连的线互不相交的情况下,一共最多能够连接多少条线。

读题时难以想象它和最长上升子序列有什么联系 ,但只要画图模拟一下思路就会十分明朗。(然而这个图出现了一些问题,其中上方的数字并非是坐标点,可以理解为12、26、18分别对应的是 a,c,b ,其中 c 在 b 的左侧,防止思维上出现偏差)

请添加图片描述
对于 A、B 组合,其对应的分别是 12,18;对于 A、C 组合,对应的分别是 12,26;对于 B、C 组合,对应的分别是 26,18;而在这三种情况中,只有选择 BC 时不符合条件,原因是下端 C 在 B 的右侧,而上方对应的 26 却在 18 的左侧,从而产生交叉的情况。

由此不难看出,若在某侧选择的两个点的位置是递增的,则在另一侧对应的两点也应该是递增的,否则将会出现两条线交叉的情况。

因此,本题便可转化为对某一侧的端点进行排序之后,求另一侧的最长上升子序列的长度。

参考代码

#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;
typedef pair<int,int> pii;
pii p[N];
int f[N];

int main(){
    
    
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>p[i].first>>p[i].second;
	}
	sort(p+1,p+n+1);
	for(int i=1;i<=n;i++){
    
    
		f[i]=1;
		for(int j=1;j<i;j++){
    
    
			if(p[i].second>p[j].second)
				f[i]=max(f[i],f[j]+1);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
    
    
		ans=max(ans,f[i]);
	}
	cout<<ans<<endl;
	
	return 0;
}

ps:由于数据范围限制,仅能通过 acwing 上的该题,洛谷则会 TLE。

猜你喜欢

转载自blog.csdn.net/laysan/article/details/121118482