题目描述
输入描述
输出描述
输入样例
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。