【集训Day4 动态规划】轮船问题

轮船问题(ship)
【问题描述】
某国家被一条河划分为南北两部分,在南岸和北岸总共有N对城市,每一城市在对岸都有唯一的友好城市,任何两个城市都没有相同的友好城市。每一对友好城市都希望有一条航线来往,于是他们向政府提出了申请。由于河终年有雾。政府决定允许开通的航线就互不交叉(如果两条航线交叉,将有很大机会撞船)。兴建哪些航线以使在安全条件下有最多航线可以被开通。
【输入格式】(ship.in)
第一行两个由空格分隔的整数x,y,10〈=x〈=6000,10〈=y〈=100。x表示河的长度而y表示宽。
第二行是一个整数N(1<=N<=5000),表示分布在河两岸的城市对数。接下来的N行每行有两个由空格分隔的正数C,D(C、D〈=x〉,描述每一对友好城市与河起点的距离,C表示北岸城市的距离而D表示南岸城市的距离。在河的同一边,任何两个城市的位置都是不同的。
【输出格式】(ship.out)
要在连续的若干行里给出每一组数据在安全条件下能够开通的最大航线数目。
【输入样例】
30 4
5
4 5
2 4
5 2
1 3
3 1
【输出样例】
3
【解题思路】
将两岸的友好城市用一个结构体存起来,以其中一个城市作为关键字进行排序,那么之后另一个城市其实会呈最长上升子序列,例如A岸城市1(A岸城市1的意思是距离河的起点为1的A岸城市)和B岸城市3之间如果开通航线,那么以后的城市都不可能向B岸城市1、2、3开通航线。那么也就呈最长上升子序列状,只要套用模板求出最长即可。
【解题反思】

  • 个人认为河的长度和宽度没有什么用
  • 一定要排序

【参考程序】

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct data
{
    int c1,c2;
}a[5001];
bool comp(data a,data b)
{
    return a.c1<b.c1;
}
int x,y,n,maxans,dp[5001];
int main()
{
    freopen("ship.in","r",stdin);
    freopen("ship.out","w",stdout);
    cin>>x>>y;
    cin>>n;
    for (int i=1;i<=n;i++) cin>>a[i].c1>>a[i].c2;
    sort(a+1,a+1+n,comp);
    for (int i=1;i<=n;i++)
        for (int j=0;j<i;j++)
            if (a[i].c2>[j].c2) dp[i]=max(dp[i],dp[j]+1);
            else dp[i]=max(1,dp[i]);
    for (int i=1;i<=n;i++) maxans=max(maxans,dp[i]);
    cout<<maxans;
    return 0;
}

2018年5月6日更新,把判断的等号去掉了

posted @ 2017-08-23 10:25  Nanjo  阅读(455)  评论(0编辑  收藏  举报