首先此一眼就能看出来是一个非常基础的最长不下降子序列(LIS),其朴素的 N^2做法很简单,但如何将其优化成为N*logN?

我们不妨换一个思路,维护一个f数组,f[x]表示长度为x的LIS的最大的最后一个数字是f[x]。(为什么是最大的?可以应用贪心的思想,发现对于相同的x,f[x]越大其后可能扩展的情况就越多,即就越优)我们可以发现f数组单调递减(为什么?也可使用反证法证明,在此不赘述)对于决策单调性问题,一般使用二分法优化,这就是logN的来历。二分的边界条件一定要写对。

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
using namespace std;
int read(){
int rv=0,fh=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') fh=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
rv=(rv<<1)+(rv<<3)+c-'0';
c=getchar();
}
return fh*rv;
}//快读
int num[100005],f[100005],q[100005];
int find1(int x){
int l=1,r=f[0],m=0;
while(l<=r){
m=(l+r)>>1;
if(f[m]>=x){
l=m+1;
}else{
r=m-1;
}
}
//if(l<=f[0]) return l;
if(r>=1) return r;
return 0;
}
int find2(int x){
int l=1,r=f[0],m;
while(l<=r){
m=(l+r)>>1;
if(f[m]>=x){
r=m-1;
}else {
l=m+1;
}
}
if(r>=1) return r;
return 0;
}
int main(){
freopen("in.txt","r",stdin);
while(scanf("%d",&num[++num[0]])==1) ;
num[0]--;//一定要减
f[1]=num[1];f[0]++;
for(int i=2;i<=num[0];i++){
int pos=find1(num[i]);
if(pos){
if(f[0]==pos) f[0]++;
f[pos+1]=max(f[pos+1],num[i]);
//cout<<f[pos+1]<<endl;
}else {
f[1]=max(f[1],num[i]);
}
}
cout<<f[0]<<endl;
for(int i=1;i<=f[0];i++){
f[i]=1000005;
}
f[0]=1;
f[1]=num[1];
for(int i=2;i<=num[0];i++){
int pos=find2(num[i]);
if(pos){
if(f[0]==pos) f[0]++;
f[pos+1]=min(f[pos+1],num[i]);
}else {
f[1]=min(f[1],num[i]);
}
}
cout<<f[0];
fclose(stdin);
return 0;
}

对于第二问,可使用dilworth定理,翻译成通俗易懂的语言就是:

对于一个序列,其最少的不降子序列划分=最长上升子序列长度,所以对于第二问输出最长上升子序列长度即可。

洛谷 [P1020] 导弹拦截 (N*logN)的更多相关文章

  1. codevs1044 拦截导弹==洛谷 P1020 导弹拦截

    P1020 导弹拦截 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天 ...

  2. 洛谷 P1020导弹拦截题解

    洛谷链接:https://www.luogu.org/problem/P1020 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到 ...

  3. 洛谷 P1020 导弹拦截(dp+最长上升子序列变形)

    传送门:Problem 1020 https://www.cnblogs.com/violet-acmer/p/9852294.html 讲解此题前,先谈谈何为最长上升子序列,以及求法: 一.相关概念 ...

  4. codevs——T1044 拦截导弹 || 洛谷——P1020 导弹拦截

    http://codevs.cn/problem/1044/ || https://www.luogu.org/problem/show?pid=1020#sub 时间限制: 1 s  空间限制: 1 ...

  5. 洛谷P1020 导弹拦截【单调栈】

    题目:https://www.luogu.org/problemnew/show/P1020 题意: 给定一些导弹的高度. 一个导弹系统只能拦截高度不增的一系列导弹,问如果只有一个系统最多能拦截多少导 ...

  6. 洛谷P1020导弹拦截——LIS

    题目:https://www.luogu.org/problemnew/show/P1020 主要是第二问,使用了dilworth定理:一个序列中最长不上升子序列的最大覆盖=最长上升子序列长度. di ...

  7. 洛谷 - P1020 - 导弹拦截 - 最长上升子序列

    https://www.luogu.org/problemnew/show/P1020 终于搞明白了.根据某定理,最少需要的防御系统的数量就是最长上升子序列的数量. 呵呵手写二分果然功能很多,想清楚自 ...

  8. 洛谷P1020 导弹拦截 题解 LIS扩展题 Dilworth定理

    题目链接:https://www.luogu.com.cn/problem/P1020 题目大意: 给你一串数,求: 这串数的最长不上升子序列的长度: 最少划分成多少个子序列是的这些子序列都是不上升子 ...

  9. 洛谷P1020 导弹拦截

    n²谁都会打,不说了. 这里讨论一下nlogn算法(单调不减): 首先开始考虑单调性,我习惯性的以为是单调队列/栈优化的那个套路,想要找到一个跟下标有关的单调性却发现没有. 例如:我想过当下标增加时f ...

随机推荐

  1. zookeeper的安装以及启动jps进程

    2.7.1安装 将下载好的安装包,解压到指定位置,这里为直接解压到当前位置,命令如下: tar -zxvf zk-{version}.tar.gz 修改zk配置,将zk安装目录下conf/zoo_sa ...

  2. 微信小程序实现滚动加载更多

    1.需要用到的组件和api scroll-view(可滚动视图区域) wx.showToast(OBJECT)显示消息提示窗----显示loading小菊花用的 2.需要用到的属性 3.scrol-v ...

  3. 从零开始学习前端开发 — 10、HTML5新标签及表单控件属性和属性值

    一.html5新增标签 1.结构性标签 header 定义网页的头部 nav 定义网页的导航 footer 定义网页的底部 section 定义网页的某个区域 article 定义网页中的一篇文章 a ...

  4. Oracle:对用户的CREATE、ALTER、GRANT、REVOKE操作练习

    --创建一个用户yong2,yong2的表空间为users,临时表空间为temp,users的表空间大小为10M,密码立刻过期,用户锁定. CREATE USER yong2IDENTIFIED BY ...

  5. 微信小程序 PHP后端form表单提交实例详解

    微信小程序php后端form表单 https://www.cnblogs.com/tdalcn/p/7092716.html 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了 ...

  6. hive下UDF函数的使用

    1.编写函数 [java] view plaincopyprint?package com.example.hive.udf;    import org.apache.hadoop.hive.ql. ...

  7. SSH中post提交表单action中文乱码问题

    我的问题对应的解决方案是:web.xml中filter的顺序问题[置顶].需要将编码过滤器放置在所有过滤器之前. 在解决这个问题途中学习到的东西: 解决方案总结(post中文乱码): 前后台编码方式一 ...

  8. JXLS使用方法(文件上传读取)xlsx文件读取

    1.官方文档:http://jxls.sourceforge.net/reference/reader.html 2.demo git地址:https://bitbucket.org/leonate/ ...

  9. Win8无法访问xp共享的解决方法——win8网上邻居访问别的xp电脑要用户名和密码取消方法

    新装win8,原来的win7正常连接xp下载机的共享,但在win8下进网上邻居却无法访问xp的共享,显示”用户名或密码不正确”,而密码明明是对的如图所示: 解决方法: 按Win+R启动运行,输secp ...

  10. linux_操作系统

    如何查询操作系统版本? cat /etc/redhat-release 什么是操作系统? -- win10,linux都是os,应用软件和硬件打交道中间桥梁软件,管理 硬件+软件 资源,计算机系统基础 ...