青少年编程知识记录 codecoming

【题解目录】友好城市

【题目描述】

Palmia国有一条横贯东西的大河,河有笔直的南北两岸,岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同。

每对友好城市都向政府申请在河上开辟一条直线航道连接两个城市,但是由于河上雾太大,政府决定避免任意两条航道交叉,以避免事故。编程帮助政府做出一些批准和拒绝申请的决定,使得在保证任意两条航线不相交的情况下,被批准的申请尽量多。

【输入描述】

第1行,一个整数N(1≤N≤5000),表示城市数。



第2行到第n+1行,每行两个整数,中间用1个空格隔开,分别表示南岸和北岸的一对友好城市的坐标。(0≤xi≤10000)

【输出描述】

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

【样例输入】

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

【样例输出】

4



【题目分析】

  1. 注意,每个城市只能建一个桥

  2. 桥和桥之间不能相连

  3. 按照测试样例,我们可以画出如下图:

从上图可以看出,最优解是

(4,2)

(9,8)

(15,12)

(17,17)



可以看出,将某一侧的城市位置进行排序后

在对岸的友好城市位置的最长上升子序列的长度 即为 桥最多能建立的数量

【参考答案】



#include <bits/stdc++.h>  using namespace std;  int dp[5005];  //对应关系的结构体   struct point{  	int first;  //友好城市的南岸   	int second; //友好城市的北岸   };  point a[5005];   bool cmp(point q1,point q2){  	return q1.first<q2.first;  }  int main()  {  	int n;  	cin>>n;  	for(int i=1;i<=n;i++)  	{  		cin>>a[i].first>>a[i].second;  //输入一组数据   	}  	sort(a+1,a+n+1,cmp); //排序   	for(int i=1;i<=n;i++)  	{  		dp[i]=1; //每次开始重置   		for(int j=1;j<i;j++)  		{  			if(a[i].second>a[j].second)  			{  				dp[i]=max(dp[i],dp[j]+1);  			}  		}  	}  	int ans=0;  	for(int i=1;i<=n;i++)   		ans=max(dp[i],ans);  //求最长上升子序列   	cout<<ans;  	return 0;  }



(adsbygoogle = window.adsbygoogle || []).push({});