zoukankan      html  css  js  c++  java
  • NOIP普及 导弹拦截 题解

    题目描述
    某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

    输入导弹依次飞来的高度(雷达给出的高度数据是le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

    输入格式
    11行,若干个整数(个数le 100000≤100000)

    输出格式
    22行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

    输入输出样例
    输入 #1复制
    389 207 155 300 299 170 158 65
    输出 #1复制
    6
    2

    趁着做了一道二分,再次复习一下lower_bound和upper_bound(虽然本题我的代码并没有使用到)。

    lower_bound(first, last, val); 查找在[first, last)中大于等于目标值的第一个元素。

    upper_bound(first, last, val); 查找在[first, last)中大于目标值的第一个元素。

    题目分析:

    很显然第一个问题求的是非上升子序列的最大长度,有n2做法,也有nlogn做法,因为本题会卡n2做法,所以要用到二分优化,采用nlogn的做法来求解。

    第二个问题求整个序列中非上升子序列的序列数,通过分析两个序列的位置关系可知就是变相问你整个序列中严格上升子序列的长度。于是也可以用nlogn 的方法来求解。

    AC CODE:
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 100010;
    
    int a[N];
    int q[N];
    int p[N];
    int f[N];
    int n;
    
    int main()
    {
        while (cin >> a[n ++ ]);
        
        int len = 0;
        for (int i = 0; i < n - 1; i ++ )
        {
            int l = 0, r = len;
            while (l < r)
            {
                int mid = l + r + 1 >> 1;
                if (q[mid] >= a[i]) l = mid;
                else r = mid - 1;
            }
            len = max(len, r + 1);
            q[r + 1] = a[i];
        }
        
        printf("%d
    ", len);
        
        len = 0;
        for (int i = 0; i < n - 1; i ++ )
        {
            int l = 0, r = len;
            while (l < r)
            {
                int mid = l + r + 1 >> 1;
                if (p[mid] < a[i]) l = mid;
                else r = mid - 1;
            }
            len = max(len, r + 1);
            p[r + 1] = a[i];
        }
        
        printf("%d
    ", len);
        
        return 0;
    }
    
  • 相关阅读:
    poj 1789 每个字符串不同的字母数代表两个结点间的权值 (MST)
    poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题
    poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
    hdu 5256 最少修改多少个数 能使原数列严格递增 (LIS)
    hdu 1025 上面n个点与下面n个点对应连线 求最多能连有多少条不相交的线 (LIS)
    Gym 100512F Funny Game (博弈+数论)
    UVa 12714 Two Points Revisited (水题,计算几何)
    UVa 12717 Fiasco (BFS模拟)
    UVa 12718 Dromicpalin Substrings (暴力)
    UVa 12716 && UVaLive 6657 GCD XOR (数论)
  • 原文地址:https://www.cnblogs.com/scl0725/p/14021241.html
Copyright © 2011-2022 走看看