友好城市

题目描述

Palmia国有一条横贯东西的大河,河有笔直的南北两岸,岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同。
每对友好城市都向政府申请在河上开辟一条航线连接两个城市,但是由于河上经常起大雾,政府决定避免任意两条航线交叉,以避免事故。请编程帮助政府做出一些批准和拒绝申请的决定,使得在保证任意两条航线不相交的情况下,被批准的申请尽量多。

输入

第1行,一个整数N(1<=N<=5000),表示城市数。
第2行到第n+1行,每行两个整数,分别表示南岸和北岸的一对友好城市的坐标。(0<=xi<=10000)

输出

一行,输出一个整数,表示政府所能批准的最多申请数。

输入样例

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

输出样例

4

分析

先分析对于任意两条航线不相交的情况。我们很容易得出排序后求最长不下降子序列。只是要优化

代码

//友好城市 n log n,最长不下降子序列 
#include<bits/stdc++.h>
using namespace std;
const int SJ=100012;
struct friends
{
	int N,S;
}p[SJ];
int ans[SJ],len=1,n;
bool cmp(friends x,friends y)
{
	return x.N<y.N;
}
int half(int l,int r,int now)
{
	while(l<=r)
	{
		int m=(l+r)>>1;
		if(ans[m]>p[now].S&&ans[m-1]<=p[now].S)
		 return m;
		else if(ans[m]<p[now].S)
		 l=m+1;
		else
		 r=m-1;
	}
	return l;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	 scanf("%d%d",&p[i].N,&p[i].S);
	sort(p+1,p+n+1,cmp);
	ans[1]=p[1].S;
	for(int i=2;i<=n;i++)
	 if(p[i].S>ans[len])
	  ans[++len]=p[i].S;
	 else ans[half(1,len,i)]=p[i].S;
	printf("%d\n",len);
}

猜你喜欢

转载自blog.csdn.net/qq_43034907/article/details/83065023