最长公共子序列 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;
}