【题解目录】友好城市
【题目描述】
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
【题目分析】
注意,每个城市只能建一个桥
桥和桥之间不能相连
按照测试样例,我们可以画出如下图:
从上图可以看出,最优解是
(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({});