zoukankan      html  css  js  c++  java
  • 最长上升子序列(LIS)

    O(nlogn)

    q[i]表示所有不同长度的最长上升子序列结尾的最小值。因为如果a[i]<a[j]<a[j+1],那么a[j+1]肯定大于a[i],因此我们只存最小值。

    我们通过第i-1个数字来划分状态,由于子序列是递增的,所以可以通过二分查找出来小于a[i]的最大的那个数字。找到之后,将a[i]放在它之后,长度加一。并且由于子序列是递增的,那么若找到的数字为a[k],那么a[k+1]一定大于等于a[i]。所以可以用a[i]来更新a[k+1].

    #include<iostream>
    #include<cmath>
    using namespace std;
    
    const int maxn=1e5+10;
    int a[maxn];
    int q[maxn];//所有不同长度的最长上升子序列结尾的最小值
    int main()
    {
    
        int n;
        cin >> n;
        for(int i=0;i<n;i++)
        {
            cin >> a[i];
        }
        int len=0;//最长上升子序列的长度
        //q[0]=-2e9;
        for(int i=0;i<n;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];
        }
        cout << len << endl;
        return 0;    
    }
  • 相关阅读:
    Luogu 1514 引水入城
    HDU 2196 Computer
    CF460C Present
    初等数论整理
    2019UMS培训day6解题报告
    2019UMS培训day5解题报告
    2019UMS培训day3解题报告
    Luogu 1731 生日蛋糕
    JavaWeb之ServletContext域对象
    c3p0连接池
  • 原文地址:https://www.cnblogs.com/wjc2021/p/11938811.html
Copyright © 2011-2022 走看看