zoukankan      html  css  js  c++  java
  • HDU 1257 最少拦截系统【LIS】

    题意:类似于套娃娃,问最少需要多少个拦截系统。

    思路:

    假设已经有m个导弹拦截序列

    r1:x11>=x12>=x13>=...>=x1n

    r1:x21>=x22>=x23>=...>=x2n
    .

    .

    rm:xm1>=xm2>=xm3>=...>=xmn

    则必定有有一个序列x1i<x2i<x3i<...<xmi,证明:

    若rx中最小比他后边某个序列的所有元素都要大的话,这两个序列必定能合成一个序列。

    如r1:8,5,4

     r2:3,2,1

    因此序列x1i<x2i<x3i<...<xmi的长度就是所求的长度。

    另,原序列的最长严格上升序列的长度的就是该序列的长度。证明:

    若存在最长严格上升子序列:xj1<xj2<xj3<...<xjk

    很明显,则xj2与xj1不可能属于同一个r,后同。故得证。

    故原问题就转换成求最长严格上升子序列的长度。

    类似的题目还有:http://acm.hdu.edu.cn/showproblem.php?pid=1677

    以上结论的证明是本人第一次完全靠自己写的证明,必定有所纰漏,甚至完全错误。写在此并不是为了让看官们背住结论就算了,更希望许多像我一样的菜鸟能够自己动手证明一些东西,这样你对于这个知识点的理解必定会上一层楼。希望大神们指正。

    #include<stdio.h>
    #include<string.h>
    const int N=1111;
    int a,d[N];
    int main(){
        int n,i,ans;
        while(~scanf("%d",&n)){
            d[0]=-1;ans=0;
            for(i=1;i<=n;i++){
                scanf("%d",&a);
                if(a>d[ans]){
                    d[++ans]=a;
                }else{
                    int l=1,r=ans;
                    while(l<=r){
                        int mid=(l+r)>>1;
                        if(d[mid]>a)    r=mid-1;
                        else            l=mid+1;
                    }
                    d[l]=a;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    css控制英文内容自动换行問題
    jquery添加select option两种代码思路比较
    C++实现单例模式
    C++实现单例模式
    windows下socket编程:区分shutdown()及closesocket()
    windows下socket编程:区分shutdown()及closesocket()
    socket关闭
    socket关闭
    C++模板的一些巧妙功能
    C++模板的一些巧妙功能
  • 原文地址:https://www.cnblogs.com/L-King/p/5763989.html
Copyright © 2011-2022 走看看