将所有航线的其中一边排序后,另一边进行类dp

定义一个数组c,c[i]表示在所有能够开通i条航线的组合中,位置序号最大的那条航线的序号的最小值

比如下面一个样例

1 3

2 4

3 1

4 2

此时对于航线左边的位置序号已经是排好序的了

那么只需要考虑右边的情况

在所有只开通1条航道的组合中

右侧出现的结果可能是{1},{2},{3},{4}

所以c[1]=1

在所有只开通2条航道的组合中

右侧出现的结果可能是{3,4},{1,2}

这里有两个组合,每个组合位置序号最大的元素分别是4和2,取小

得到c[2]=2

同时我们可以发现c数组是严格递增的

那么定义完了c数组,说下它有什么用

因为航线左端排好序,每次考虑的值都是右端序号

重新举个例子

1 4

2 5

3 1

4 2

5 3

只拿右端序列,得到dp对象为4 5 1 2 3

考虑4,得到c[1]=4,答案更新为1

考虑5,因为5>4,且左侧序号递增,所以可以得到这条航线与终点为4的航线不重叠,可以组合,所以c[2]=5,答案更新为2

考虑1,因为c数组内没有元素比1小,所以更新c[1]=1,答案不变,为2

考虑2,得到c[1]<2,所以可以和此时c[1]指代的航线组合,更新c[2]=2,答案不变,为2

考虑3,得到c[2]<3,所以可以和此时c[2]指代的2条航线组合,c[3]=3,答案更新为3

首先,答案就是能够组合在一起的最大数量,即c数组最大的下标

那么为什么可以这样更新呢?

从形式上看,更新了数组之后相当于破坏了前面的航线的结论(看上去会让前面的航线交叉)

实际上,因为每考虑到一个点的时候,可以视为前面的点能组合的都已经组合完毕

更新c数组的元素,是为了贪心让之后的点加进来后对答案贡献更大,让其后的点能有更优的组合

对于代码实现,取用lower_bound函数或者手动模拟二分查找(已知现有c数组是有序的)

#include<iostream>
#include<algorithm>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
const int m=;
struct line{
int a,b;
bool operator < (const line& x) const{
return a<x.a;
}
}r[m];
int c[m];
int main(){
ios::sync_with_stdio();
cin.tie();cout.tie();
int T,n,i,p,ans;
cin>>T;
while(T--){
cin>>n;
for(i=;i<=n;i++)
cin>>r[i].a>>r[i].b;
sort(r+,r++n);
memset(c,INF,sizeof c);
ans=;
for(i=;i<=n;i++){
p=lower_bound(c+,c++ans,r[i].b)-c;
ans=max(ans,p);
c[p]=r[i].b;
}
cout<<ans<<endl;
} return ;
}

ZJNU 1217 - 航线问题——高级的更多相关文章

  1. ZJNU 1223 - 素数距离——高级

    因为最大可以达到int极限 明显直接筛选不可能完成 所以从其因子入手 因为任何不是素数的数都有除了1与其自身之外的因子 因此,我们筛出2^(31/2)≍46350之内的所有素数,以其作为因子再将题目给 ...

  2. ZJNU 1205 - 侦探推理——高级

    双层枚举嫌疑犯与当日是星期几,统计真话与假话是否满足题意 注意 fake<=N&&fake+neutral>=N 即假话数量不大于N,假话加上没用的废话数量不小于N (注意 ...

  3. hdu 3047 Zjnu Stadium 并查集高级应用

    Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  4. ZJNU 1538 - YN!ngC的取子游戏--高级

    Nim博弈 因为移动到第0阶会消失 所以可以得到从最后一个人操作必定是把第1阶所有子全部移动到第0阶 递推可得,最后一个能把奇数阶的子移动到偶数阶上的人将会必胜 所以这个必胜条件就是奇数阶上的子全部为 ...

  5. ZJNU 1367 - Party--中高级

    寻找从i到X,再从X到i的最短路 可以在正向图中从X开始跑一遍最短路,每个点的距离dis1[i]当作从X回到点i的距离 再将图反向从X再跑一遍,每个点的距离dis2[i]当作从i到点X的距离 最后搜索 ...

  6. ZJNU 1333 - 第二题 blocks--中高级

    因为放一个就需要判断一次,每一次跑一遍全图bfs显然是不现实的 又因为点只有三种,黑白无 所以可以用并查集优化 添加一个棋子就判断周围四个的组别情况 注意出现的情况与答案关系之间的判别 /* Writ ...

  7. ZJNU 1269 - 灯塔——高级

    根据题目输入可以得到一个有向图 信号可以根据有向图的传递性传递,因此可以说是找到这个有向图的所有父亲即可 但又要考虑可能会出现环这类情况 所以跑一遍强连通分量模板,再根据分块后的图找到入度为0的块,把 ...

  8. ZJNU 1244/1245 - 森哥数——高级

    打表找规律吧…… 一定要记得每一步都得开long long 然后可以发现所有的森哥数每一位只可能是0,1,2,3 就可以想到最高O(3^9)的算法 枚举1e9之内的所有满足条件的数判断 枚举9位数,最 ...

  9. ZJNU 1213 - 取水——高级

    某个村庄i可以打一口井取水花费费用Wi,也可以与有水的村庄连接取水 又因为不可能没有一个村庄不打井(即至少有一个村庄打井,其余村庄连向它) 实际上就可以理解为,将水井看作第N+1个村庄,需要有村庄与这 ...

随机推荐

  1. 前端第三篇---前端基础之JavaScript

    前端第三篇---前端基础之JavaScript 一.JavaScript概述 二.JavaScript的基础 三.词法分析 四.JavaScript的内置对象和方法 五.BOM对象 六.DOM对象 七 ...

  2. RF:connecting to multiple databases

    Hello, I am trying to connect to multiple databases with DatabaseLibrary but its not working. *** Se ...

  3. c++程序—字符串

    C风格字符串:char 变量名[ ]="字符串值 " int main() { char str[] = "hello world!"; cout <&l ...

  4. CodeForces - 402B Trees in a Row (暴力)

    题意:给定n个数,要求修改其中最少的数,使得这n个数满足ai + 1 - ai = k. 分析: 暴力,1000*1000. 1.这n个数,就是一个首项为a1,公差为k的等差数列.k已知,如果确定了a ...

  5. 在开发过程中遇到的Oracle的坑及开发技巧

    本人与2018年毕业,工作一年多,仍是菜鸟,自毕业以来一直从事java软件开发工作,工作中大部分数据库都是使用的Oracle,碰到的问题总结一下(随时更新). 1.sql中使用group by 分组时 ...

  6. 九、CI框架之将URI转为数组原型

    一.输入以下代码,uri_to_assoc的参数默认从3开始 二.输出效果如下: 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意金额给作者(微信号:382477247)哦, ...

  7. 七、CI框架之分配变量数组,循环输出

    一.添加并传递变量 二.在View界面输出 输出显示 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意金额给作者(微信号:382477247)哦,谢谢.

  8. 在GitHub上上传自己的项目

    1.注册一个自己的GitHub账号 2.登录,开始创建一个新的项目,填写项目名称,描述 创建完成之后,跳转到下面的页面,下面红框中的网址要记住,在后面上传代码的时候需要使用 3.下载最新版本的Git  ...

  9. js 循环与判断语句的几个练习

    <script type="text/javascript"> /*1.X3 * 6528 = 3X * 8256 X为一个数字 填入一个数字 使等式成立*/ for ...

  10. 深入理解 Java —— GC 机制

    1. 基础知识 1.1 什么是垃圾回收? 程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存资源,最终将导致内存溢出,所以对内存资源的管理非常重要. 垃圾回收就是对这些无效资 ...