【题解】轮船问题

题目描述

  某国家被一条河划分为南北两部分,在南岸和北岸总共有N对城市,每一城市在对岸都有唯一的友好城市,任何两个城市都没有相同的友好城市。每一对友好城市都希望有一条航线来往,于是他们向政府提出了申请。由于河终年有雾。政府决定允许开通的航线就互不交叉(如果两条航线交叉,将有很大机会撞船)。兴建哪些航线以使在安全条件下有最多航线可以被开通。

输入格式

  第一行,两个由空格分隔的整数x,y,10≤x≤6000,10≤y≤100。x表示河的长度而y表示宽。

  第二行是一个整数N(1≤N≤5000),表示分布在河两岸的城市对数。

  接下来的N行每行有两个由空格分隔的正数C,D(C、D≤x,描述每一对友好城市与河起点的距离,C表示北岸城市的距离而D表示南岸城市的距离。在河的同一边,任何两个城市的位置都是不同的。

输出格式

  一行,在安全条件下能够开通的最大航线数目。

输入样例

30 4

5

4 5

2

5 2

1 3

3 1

输出样例

3

题解

  题目中说互不交叉,实际上就是求最长上升子序列,套模板即可。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define MAXN 5001

using namespace std;

int x, y;
int n;
struct node
{
    int N, S;
}a[MAXN];
bool cmp(node a, node b) 
{
    if(min(a.N, a.S) != min(b.N, b.S)) 
        return min(a.N, a.S) < min(b.N, b.S); 
    return max(a.N, a.S) < max(a.N, a.S);
}
int f[MAXN];
int ans;

int main()
{
    cin >> x >> y >> n;
    for(register int i = 1; i <= n; i++)
    {
        cin >> a[i].N >> a[i].S;
    }
    sort(a + 1, a + n + 1, cmp);
    for(register int i = 1; i <= n; i++)
    {
        for(register int j = 1; j < i; j++)
        {
            if(a[i].N > a[j].N && a[i].S > a[j].S) 
            {
                f[i] = max(f[i], f[j]);
            }
        }
        ans = max(ans, ++f[i]);
        //cout << i << " " << f[i] << " " << ans << endl;
    }
    cout << ans;
    return 0;
} 
参考程序

猜你喜欢

转载自www.cnblogs.com/kcn999/p/10805162.html