1. 程式人生 > >LIS 最長上升子序列 (n*logn) 模板 (二分查詢+遞迴)

LIS 最長上升子序列 (n*logn) 模板 (二分查詢+遞迴)

      最長上升子序列是很早就接觸了的問題了,一直用的是動態規劃n*n的方法,也知道那不是最好的,可以優化,今天看部落格無意中看到LIS,LCS兩個詞,就特意找了部落格看了看,主要是理解一下這裡的思想,其實蠻複雜難懂的,自己很難說清楚,還是得引用人家的部落格才行。點選開啟連結

下面還有模板:

#include<iostream>
#include<cstring>
using namespace std;
int a[1000];
int dp[1000];
int BinarySearch(int x, int len)//二分查詢dp[]裡面第一個大於等於x的數
{
    int left=1, right=len, mid;
    while(left<=right)
    {
        mid=(left+right)/2;
        if(x==dp[mid])
            return mid;
        else if(x>dp[mid])
            left=mid+1;
        else if(x<dp[mid])
            right=mid-1;
    }
    return left;
}
int main()
{
    int N;
    while(cin>>N)
    {
        memset(dp, 0, sizeof(dp));
        for(int i=1; i<=N; i++)
        {
            cin>>a[i];
        }
        dp[1]=a[1];
        int len=1;//當前已經求出來的最長序列長度
        int j;//dp[]的下標
        for(int i=2; i<=N; i++)
        {
            //if(a[i]<dp[1])
               // j=1;
            if(a[i]>dp[len])//如果a[i]>dp[len]   len +1
                j=++len;
            else//反之, 更新j
                j=BinarySearch(a[i], len);
            dp[j]=a[i];//把a[i]更新入dp[]陣列

        }
        cout<<len<<endl;
    }
    return 0;
}