二分优化

在求一个最长不上升自序列中,显然其结尾元素越小,越有利于接其他元素,对答案的贡献也就可能会更高

那么我们可以用low[i]去存长度为i的LIS结尾元素的最小值

因此我们只要维护low数组

对于每一个a[ i ],如果a[ i ] > low [当前最长的LIS长度],就把 a [ i ]接到当前最长的LIS后面,即low [++当前最长的LIS长度] = a [ i ]。

那么,怎么维护 low 数组呢?
对于每一个a [ i ],如果a [ i ]能接到 LIS 后面,就接上去;否则,就用 a [ i ] 取更新 low 数组。具体方法是,在low数组中找到第一个大于等于a [ i ]的元素low [ j ],用a [ i ]去更新 low [ j ]。如果从头到尾扫一遍 low 数组的话,时间复杂度仍是O(n^2)。我们注意到 low 数组内部一定是单调不降的,所有我们可以二分 low 数组,找出第一个大于a[ i ]的元素。二分一次 low 数组的时间复杂度的O(lgn),所以总的时间复杂度是O(nlogn)。

例题

P2782 友好城市

先将所有城市排序,然后发现就是一个最长不下降子序列

但暴力只能拿50pts

 1 /*
2 Work by: Suzt_ilymics
3 Knowledge: ??
4 Time: O(??)
5 */
6 #include<iostream>
7 #include<cstdio>
8 #include<algorithm>
9 using namespace std;
10 const int MAXN = 2e5+5;
11 struct good{
12 int n,s;
13 bool operator < (const good &b) const {return n == b.n ? s < b.s : n < b.n; }
14 }a[MAXN];
15 int n, ans;
16 int f[MAXN];
17 int main()
18 {
19 scanf("%d", &n);
20 for(int i = 1; i <= n; ++i){
21 scanf("%d%d", &a[i].n, &a[i].s);
22 }
23
24 sort(a+1, a+n+1);
25
26 for(int i = 1; i <= n; ++i){
27 f[i] = 1;
28 for(int j = 1; j < i; ++j){
29 if(a[j].n < a[i].n && a[j].s < a[i].s){
30 f[i] = max(f[i], f[j] + 1);
31 }
32 }
33 ans = max(ans, f[i]);
34 }
35
36 printf("%d", ans);
37
38 return 0;
39 }

考虑一下上面的优化,因为北岸的城市是排好的,所以low数组里只需存南岸

 1 /*
2 Work by: Suzt_ilymics
3 Knowledge: LIS + 二分优化
4 Time: O(nlogn)
5 */
6 #include<iostream>
7 #include<cstdio>
8 #include<algorithm>
9 #define INF 2100000000
10 using namespace std;
11 const int MAXN = 2e5+5;
12 struct good{
13 int n,s;
14 bool operator < (const good &b) const {return n == b.n ? s < b.s : n < b.n; }
15 }a[MAXN];
16 int n, ans;
17 int f[MAXN], low[MAXN];
18
19 int ef(int r, int k){
20 int mid, l = 0;
21 while(l <= r){
22 mid = (l + r) >> 1;
23 if(low[mid] <= k){
24 l = mid + 1;
25 }
26 else{
27 r = mid - 1;
28 }
29 }
30 return l;
31 }
32
33 int main()
34 {
35 scanf("%d", &n);
36 for(int i = 1; i <= n; ++i){
37 scanf("%d%d", &a[i].n, &a[i].s);
38 low[i] = INF;
39 }
40
41 sort(a+1, a+n+1);
42
43 low[1] = a[1].s;
44 ans = 1;
45
46 for(int i = 2; i <= n; ++i){
47 if(a[i].s > low[ans]){
48 low[++ans] = a[i].s;
49 }
50 else{
51 low[ ef(ans, a[i].s) ] = a[i].s;
52 }
53 }
54
55 printf("%d", ans);
56
57 return 0;
58 }

LIS的优化的更多相关文章

  1. POJ 3903:Stock Exchange(裸LIS + 二分优化)

    http://poj.org/problem?id=3903 Stock Exchange Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  2. LIS的优化算法O(n log n)

    LIS的nlogn的优化:LIS的优化说白了其实是贪心算法,比如说让你求一个最长上升子序列把,一起走一遍. 比如说(4, 2, 3, 1, 2,3,5)这个序列,求他的最长上升子序列,那么来看,如果求 ...

  3. HDU 1025 LIS二分优化

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Time Limit: ...

  4. HDU 1025:Constructing Roads In JGShining's Kingdom(LIS+二分优化)

    http://acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Problem Des ...

  5. 【模板】最长上升子序列(LIS)及其优化 & 洛谷 AT2827 LIS

    最长上升子序列 传送门 题意 对于给定的一个n个数的序列,找到它的一个最长的子序列,并且保证这个子序列是由低到高排序的. 例如,1 6 2 5 4 6 8的最长上升子序列为1 2 4 6 8. 基本思 ...

  6. CF 809 D Hitchhiking in the Baltic States —— 思路+DP(LIS)+splay优化

    题目:http://codeforces.com/contest/809/problem/D 看题解,抄标程...发现自己连 splay 都快不会写了... 首先,题目就是要得到一个 LIS: 但与一 ...

  7. UVA1471( LIS变形)

    这是LIS的变形,题意是求一个序列中去掉某个连续的序列后,能得到的最长连续递增序列的长度. 用DP的解法是:吧这个序列用数组a来记录,再分别用两个数组f记录以i结尾的最长连续递增序列的长度,g[i]记 ...

  8. 最长递增子序列( LIS)

    LIS LIS的优化说白了其实是贪心算法,比如说让你求一个最长上升子序列把,一起走一遍. 比如说(4, 2, 3, 1, 2,3,5)这个序列,求他的最长上升子序列,那么来看,如果求最长的上升序列,那 ...

  9. hdu 1257 最少拦截系统【贪心 || DP——LIS】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...

随机推荐

  1. SAML和OAuth2这两种SSO协议的区别

    目录 简介 SAML SAML的缺点 OAuth2 OAuth2的缺点 两者的对比 CAS简介 简介 SSO是单点登录的简称,常用的SSO的协议有两种,分别是SAML和OAuth2.本文将会介绍两种协 ...

  2. 树莓派(4B)新手入门教程

    前期准备 必要物料 树莓派4B 主机 Type-C 电源 内存卡(8G+) 一般建议一步到位64G 系统镜像 镜像写入工具 下载地址 镜像下载 官方下载地址: https://www.raspberr ...

  3. .Net微服务实战之负载均衡(下)

    系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术架构分层篇 .Net微服务实战之DevOps篇 .Net微服务实战之负载均衡(上) .Net微服务实战之CI/CD .Net微服务实战 ...

  4. Appium 介绍及环境安装

    Appium是一个可用于测试iOS. Android操作系统和Windows桌面平台原生应用,移动网页应用和混合应用的自动化测试框架. 原生应用(Native App):用 android.iOS或者 ...

  5. 剑指offer-查找数组中重复的数字

    找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重 ...

  6. python常见题型

    语言特性 1. 谈谈对 Python 和其他语言的区别 2. 简述解释型和编译型编程语言 3. Python 的解释器种类以及相关特点? 4. Python3 和 Python2 的区别? 5. Py ...

  7. Java开发手册之设计规约

    1.谨慎使用继承的方式来进行扩展,优先使用聚合/组合的方式来实现.说明:不得已使用继承的话,必须符合里氏代换原则,此原则说父类能够出现的地方子类一定能够出现,比如,"把钱交出来", ...

  8. 系统吞吐量与QPS/TPS

    QPS/TPS QPS:Queries Per Second意思是"每秒查询率",是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准. ...

  9. 【Linux】ssh远程连接到指定ip的指定用户上

    通过ssh可以远程连接到其他的机器上,但是如果只想连接到指定的用户的话 需要这样做: -l 选项 (是L不是I,小写) ssh IP -l 用户名 这里的ip如果在hosts下就可以直接输入域名或者主 ...

  10. ctfhub技能树—RCE—命令注入

    打开靶机 查看页面信息 输入127.0.0.1进行测试 构造payload 127.0.0.1&ls 查看文件内容信息 127.0.0.1 & cat 179852221619745. ...