首页 > 其他分享 >[NOIP1999 普及组] 导弹拦截

[NOIP1999 普及组] 导弹拦截

时间:2023-01-08 21:00:34浏览次数:64  
标签:普及 int missile rg NOIP1999 LIS 序列 拦截 include

题目传送门

分析

 1e5的数据,要nlogn才能过
 第一问求的是 最长不上升序列, 第二问求的是 最少的不上升子列个数

第一问:

传统的dp求LIS是 \(n^2\) 的复杂度,事实上第二层循环可以优化到logn
这里针对本题阐述一下口胡一下

对于第i个数x,如果x小于等于序列当前元素时,直接加入到序列中
如果x大于序列当前元素时,在序列中二分查找到小于x的最大值的位置,用x替换掉原来的值
 ps:可以注意到此时保存的序列很大可能就不是LIS序列,但是它的最终的长度一定是LIS长度
 这样子更新可以理解为既不破坏原来的最长序列的结构,同时也能使该序列具有更大的延续性(因为用了一个更大的x接替了原来小一点的数)
但是这样子最终只能得到LIS的长度,没法得到序列,目前还没有想出求序列的办法

第二问:

luogu题解中很多可以证明实际上就是求最长公共上升序列的,但是我不会证明
和第一问的logn处理有类似的联想,我想到的是对于每一个新加入的数x,应该找到各系统中当前高度大于等于x的最小值,把x接在后面
最优性解释是如果把x放在了另外一个系统上,那么下一个比x大一点的数就不一定能放到当前系统中
以上用数学表示就是,存在两个系统当前高度为a, a + 1;
此时新加入的一个数x = a,那么把x放在高度为a的系统肯定比放在高度为a + 1的系统更优,
因为如果下一个数x = a + 0.5,此时就没办法放到当前的系统中了。
过程可以用平衡树维护,STL中set还可以做到直接查询大于等于x的最小值的位置,见代码

代码

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
#define rg register
inline int read(){
    rg int x = 0, f = 1;
    rg char c = getchar();
    while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}
const int N = 1e5 + 1, max_h = 5e4 + 1;
int n, prein;
int a[N];
set<int> q;
int missile[N];

inline void init(){
    while (scanf("%d", &prein) != EOF)
        a[++n] = prein;
}

inline void doit(){
    int sum = 0;
    missile[0] = max_h;
    for (int i(1); i <= n; ++i){
        if (a[i] <= missile[sum]) missile[++sum] = a[i];
        else {
            int l = 1, r = sum;
            while (l < r){
                int mid = l + r >> 1;
                if (missile[mid] < a[i]) r = mid;
                else l = mid + 1; 
            }
            missile[l] = a[i];
        }
        set<int>::iterator it = q.lower_bound(a[i]);
        if (it != q.end()) 
            q.erase(it);
        q.insert(a[i]);
    }
    printf("%d\n%d", sum, q.size());
}

int main(){
    ios::sync_with_stdio(false);
    cout.tie(NULL);
    init();
    doit();
    return 0;
}

标签:普及,int,missile,rg,NOIP1999,LIS,序列,拦截,include
From: https://www.cnblogs.com/cancers/p/17035327.html

相关文章

  • SpringMVC拦截器使用
    SpringMVC拦截器拦截器是用来干什么的?在一个登录功能中,如果用户没有登录却尝试通过地址栏直接访问内部服务器资源,这显然是非法的。怎样对这些的非法访问进行拦截?SpringM......
  • SpringBoot——过滤器、监听器、拦截器
    前言在实际开发过程中,经常会碰见一些比如系统启动初始化信息、统计在线人数、在线用户数、过滤敏高词汇、访问权限控制(URL级别)等业务需求。这些对于业务来说一般上是无关......
  • springboot加入拦截器后swagger无法访问
    由于需要对用户权限进行认证,判断登录与否,然后设置了全局拦截器,然后测接口的额时候swagger也被拦截了(QAQ)拦截器不配置拦截路径时可以访问,配置后出现以下情况两种......
  • Android 数据传递的几种方式,HttpLoggingInterceptor消息拦截器
    目录​​Android数据传递的几种方式​​​​一。用intent传递​​​​二。使用bundle进行传值:​​​​三。当antivity销毁时传递数据StartActivityForResult​​​​HttpLo......
  • 一文解读C# 动态拦截第三方进程中的方法函数(外挂必备)
    一、前言由于项目需要,最近研究了一下跨进程通讯改写第三方程序中的方法(运行中),把自己程序中的目标方法直接覆盖第三方程序中的方法函数;一直没有头绪,通过搜索引擎找了一大堆......
  • Mybatis 拦截器
    1.添加依赖<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId>......
  • SpringBoot过滤器/拦截器
    不同点项过滤器拦截器使用场景对请求/响应进行修改、判断等。一般用于过滤参数、登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换。在service或者一个方法前......
  • JavaScript 中如何拦截全局 Fetch API 的请求和响应?
    本文翻译自InterceptingJavaScriptFetchAPIrequestsandresponses拦截器是可用于预处理或后处理HTTP请求的代码块,有助于全局错误处理、身份验证、日志记录等。在......
  • SpringBoot之HandlerInterceptor拦截器的使用
    ​​1、SpringBoot之HandlerInterceptor拦截器的使用——(一)​​​​2、SpringBoot之HandlerInterceptor拦截器的使用——(二)自定义注解​​​​3、SpringBoot之HandlerInte......
  • 使用拦截器拦截未认证用户请求-将你拒之门外
    拦截器将用户的某个请求前中后进行插入相应操作。preHandle调用时间:Controller方法处理之前执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行......