航线设计 (序列DP)

来源:互联网 发布:最新域名后缀 编辑:程序博客网 时间:2024/06/11 17:54

【问题描述】

  有一个国家被一条河划分为南北两部分,在南岸和北岸总共有N对城镇,每一城镇在对岸都有唯一的友好城镇。任何两个城镇都没有相同的友好城镇。每一对友好城镇都希望有一条航线来往。于是他们向政府提出了申请。由于河终年有雾。政府决定不允许有任两条航线交叉(如果两条航线交叉,将有很大机会撞船)。

  你的任务是写一个程序来帮政府官员决定他们应拨款兴建哪些航线以使得没有出现交叉的航线最多。

【输入格式】

  第一行一个整数N,表示分布在河两岸的城镇对数。接下来的N行每行有两个由空格分隔的正数C,D(C、D<=10^9〉,描述每一对友好城镇沿着河岸与西边境线的距离,C表示北岸城镇的距离而D表示南岸城镇的距离。在河的同一边,任何两个城镇的位置都是不同的。

【输出格式】

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

【输入样例】

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

【输出样例】

4

【数据范围】

  1<=N<=500000

这道题要求航线不可相交,可以考虑先把一岸的城市由坐标从小到大排序,再dp找与之相对应的另一个城市的坐标的最大上升序列的长度,这样就保证符合题目的要求。因为题目数据比较大,所以需用n*log2n的方法找最大上升序列的长度。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=500002;int n,g[maxn];//g[k]:长度为k的上升子序列的末尾元素的最小值//g数组保证单调上升,可以二分查找,使得时间复杂度减小struct data{    int n,s;};data a[maxn];bool cmp1(data a,data b){    return a.n<b.n;}int main(){    //freopen("1.txt","r",stdin);    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d %d",&a[i].n,&a[i].s);    }    sort(a+1,a+n+1,cmp1);    int cnt=0,t=0;    for(int i=1;i<=n;i++)    {        int t=lower_bound(g+1,g+1+cnt,a[i].s)-g; //二分查找最小值        if(t>cnt||g[t]>a[i].s) g[t]=a[i].s; //维护g数组        cnt=max(t,cnt);    }    printf("%d\n",cnt);    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 驾照c证扣12分怎么办 两年小车忘年审怎么办 4年车检过期了怎么办 车检过期了1周怎么办 超过检车几天了怎么办 驾驶证扣两个6分怎么办 行驶证检验有效期过期怎么办 驾驶证被扣26分怎么办 c1驾驶证扣26分怎么办 驾驶证被扣6分后怎么办 c1驾照年审过期一天怎么办 审驾照时间过了怎么办 b2驾驶证扣了分怎么办 a2驾照逾期未审怎么办 中学生只想打游戏不肯学习怎么办 汽车4年未年检怎么办 2年没有验车怎么办 驾驶证过期2年半怎么办 审车逾期一个月怎么办 摩托车驾驶证年审过期一个月怎么办 摩托车驾驶证记满12分怎么办 b2驾驶证扣2分该怎么办 b2扣6分以上怎么办 审驾照晚了3天怎么办 考驾驶证3年到期怎么办 学习驾驶证明过期了怎么办 a2扣了12分怎么办 驾照a2扣6分了怎么办 a2本扣9分怎么办 驾驶证分扣3分怎么办? 异地换驾驶证没有居住证怎么办 b2开c1车扣分怎么办 驾照五次没考过怎么办 大车行驶证丢了怎么办 车的产权证丢了怎么办 车子行驶证掉了怎么办 定期的存折丢了怎么办 存折密码输错6次怎么办 营业执照原件丢失怎么办怎么注销 违章扣了14分怎么办 c1驾驶本过期了怎么办