zoukankan      html  css  js  c++  java
  • O (n*logn)求 LIS

    LIS(O (n*logn))

    题目

    lower_bound & upper_bound用法
    假设我们查找x,那么:
    lower_bound会找出序列中第一个大于等于x的数
    upper_bound会找出序列中第一个大于x的数
    但是!!只能对升序的序列找,如果是降序的,加一个greater<int>()
     
    n*logn 求LIS的算法
    定义x[i]表示长度为 i的LIS结尾的数(定义很重要!!)
    如果求的是最长上升子序列的话,同样的i,我们希望x[i]越小越好,因为这样后面的数能接上来的可能性越大
    所以每当进来一个数a[i],如果可以接上,就将长度增加
    否则就找到第一个大于等于它的数,将那个数更新成它

    为什么是大于等于呢?
    如果有一个数是和它相等的,那么优先找到的就是相等的数,即相当于没更新
    如果改成大于,把大于它的更新成了它,就说明有两个长度结尾的数是一样的
    由于求的是最长上升,不能相同,就矛盾了

    总结
    严格上升:用lower_bound   可以相等:用upper_bound    降序序列:加greater<int>()
    #include<bits/stdc++.h>
    using namespace std;
    #define inf 2100000000
    #define N 100005
    int n=0,a[N],x1[N],x2[N],l1,l2;
    bool read()
    {
        char ch=getchar();
        if(ch==EOF) return false;
        int fl=1,x=0;
        while(ch<'0'||ch>'9') { if(ch=='-') fl=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        a[++n]=x;
        return true;
    }
    int main()
    {
        while(read());
        x1[++l1]=a[1]; x2[++l2]=a[1];
        for(int i=2;i<=n;i++){
            if(a[i]<=x1[l1]) x1[++l1]=a[i];
            else{
                int pos=upper_bound(x1+1,x1+1+l1,a[i],greater<int>())-x1;
                x1[pos]=a[i];
            }
            if(a[i]>x2[l2]) x2[++l2]=a[i];
            else{
                int pos=lower_bound(x2+1,x2+1+l2,a[i])-x2;
                x2[pos]=a[i];
            }
        }
        printf("%d
    %d
    ",l1,l2);
    } 
    //389 207 155 300 299 170 158 65
    View Code
  • 相关阅读:
    Linux下卸载mysql
    ORA-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA
    Centos系统创建用户oracle后,用该用户登陆系统,页面加载报错GConf error
    Java Web 深入分析(6) Tomcat
    CSS 类选择器
    myeclipse 破解
    Java Web 深入分析(5) Java ClassLoader 工作机制
    JFinal(2)JFinal 学习资料
    JFinal(1)JFinal helloworld
    Java Web 深入分析(4) Java IO 深入分析
  • 原文地址:https://www.cnblogs.com/mowanying/p/11388527.html
Copyright © 2011-2022 走看看