8.9 LIS,LCS

最长公共子序列 LCS(白书P56)

(The longest common subsequence,LCS)

一个数列 ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 称为已知序列的最长公共子序列。

最长公共子串

最长公共子串要求在原字符串中是连续的

最长上升子序列(白书P64)

(Longest Increasing Subsequence,LIS),在计算机科学上是指一个序列中最长的单调递增的子序列。

有两种,时间复杂度分别为O(n^2)与O(n log n),空间复杂度均为O(n)。但是第一种可以同时求出LIS本身,而第二种只能求出LIS的长度。

//给定N个数,求这N个数的最长上升子序列的长度。二分
/*【样例输入】

7

2 5 3 4 1 7 6

【样例输出】

4 */
#include<cstdio>
#include<algorithm>
const int MAXN=200001;

int a[MAXN];
int d[MAXN];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    d[1]=a[1];
    int len=1;
    for(int i=2;i<=n;i++)
    {
        if(a[i]>d[len])
            d[++len]=a[i];
        else
        {
            int j=std::lower_bound(d+1,d+len+1,a[i])-d;
            d[j]=a[i]; 
        }
    }
    printf("%d\n",len);    
    return 0;
}
#include <iostream>
using namespace std; 
int i,j,n,s,t,a[100001];
int main()
{ 
    cin>>n;
    a[0]=-1000000;
    for(i=0;i<n;i++)
    {
        cin>>t;
        if(t>a[s]) a[++s]=t;
        else
        {
            int l=1,h=s,m;
            while(l<=h)
            {
                m=(l+h)/2;
                if(t>a[m]) l=m+1;
                else h=m-1;
            }
            a[l]=t;
        }
    }
    cout<<s<<endl;
}

猜你喜欢

转载自blog.csdn.net/tingtingyuan/article/details/81540665
8.9