P1020 导弹拦截

  最近做题都没怎么发博客,这道题忍不住要发其实也就是因为这道题满分200分……数据强化过了……

  想必很多人第一眼看就是O(n2)的做法,但是这是拿不到满分的,所以当然不能那么写(我也不会那么写qwq)

  那我们就维护一个队列,每一次将一个新的元素插入队列替换原有元素或者加到队尾即可,很容易实现。

  至于第二问最少配置数量,其实就是反过来,即最长上升序列。感性地理解一下就好,其实也可以证明的(我做的时候简单证了一下),在此就不多加解释了。

  说实话,感觉这道题不应该是道黄题,它需要的思考方式再某种程度上,我感觉说是道蓝题并不夸张(毕竟O(n2)已经过不了了啊)

  那就发代码:

#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 100005
int a[maxn],b[maxn],c[maxn],n,len,str;
int main()
{
    int x;
    while(scanf("%d",&a[++n])!=EOF)
    continue;
    n--;
    //for(int i=1; i<=10; i++)
        //scanf("%d",&a[++n]);
    len=1;
    b[1]=a[1];
    for(int i=2; i<=n; i++)
    {
        if(a[i]<=b[len])
        {
            b[++len]=a[i];
            continue;
        }
        else
        {
            int l=1,r=len,mid=0;
            while(l<r)
            {
                mid=(l+r)/2;
                if(b[mid]>=a[i])
                    l=mid+1;
                else
                    r=mid;
            }
            b[l]=a[i];
        }
    }
    printf("%d
",len);
    str=1;
    c[1]=a[1];
    for(int i=2;i<=n;i++)
    {
        if(a[i]>c[str])
        {
            c[++str]=a[i];
            continue;
        }
        else
        {
            int p=lower_bound(c,c+str,a[i])-c;
            c[p]=a[i];
        }
    }
    printf("%d",str);
    return 0;
}
原文地址:https://www.cnblogs.com/popo-black-cat/p/10106002.html