1263:【例9.7】友好城市时间限制: 1000 ms 内存限制: 65536 KB 提交数: 6739 通过数: 3903 【题目描述】河有笔直的南北两岸,岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同。 每对友好城市都向政府申请在河上开辟一条直线航道连接两个城市,但是由于河上雾太大,政府决定避免任意两条航道交叉,以避免事故。编程帮助政府做出一些批准和拒绝申请的决定,使得在保证任意两条航线不相交的情况下,被批准的申请尽量多。 【输入】第1行,一个整数N(1<=N<=5000),表示城市数。 第2行到第n+1行,每行两个整数,中间用1个空格隔开,分别表示南岸和北岸的一对友好城市的坐标。(0<=xi<=10000) 【输出】仅一行,输出一个整数,表示政府所能批准的最多申请数。 【输入样例】 【输出样例】 |
教学备忘录:编辑 |
无 |
给学生提示:编辑 |
无 |
思路:通过 保证两条航线不想交 可以得到,每两条航线的两岸坐标是依次递增的
那么第一步我们可以控制某一侧的坐标是严格递增的,进行结构体排序(用两个数组冒泡排序也可以);
样例按南岸坐标排完序后:
2 6
4 2
9 8
10 3
15 12
17 17
22 4
第二步 北岸的坐标只有是递增才能保证不交叉,再找最多不交叉的数量,即递增的且最长的序列,就把这道题转化为了求最长上升子序列。
#include <iostream>
#include <algorithm>
using namespace std;
int dp[5005];
struct edge {
int south;
int north;
}city[5005];
bool cmp (edge a, edge b) {
if (a.south == b.south) return a.north < b.north;
return a.south < b.south;
}
int main()
{
int n, maxn = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> city[i].south >> city[i].north;
dp[i] = 1;
}
sort(city+1, city+n+1, cmp);
for (int i = 1; i <= n; i++) {
for (int j = 1; j < i; j++) {
if (city[j].north <= city[i].north && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
}
}
maxn = max(dp[i], maxn);
}
cout << maxn << endl;
return 0;
}