【1】
动态规划,dp;
时间复杂度:olog(n^2);
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int LIS(int a[],int alen[],int len)
{
int maxlen=1;
alen[0]=1;
for(int i=1; i<len; i++)
{
alen[i]=1;
for(int j=0; j<i; j++)
{
if(a[j]<a[i]&&alen[j]+1>alen[i])
{
alen[i]=alen[j]+1;
}
}
if(alen[i]>maxlen)
{
maxlen=alen[i];
}
}
return maxlen;
}
int main()
{
int n;
int a[100];
int alen[100];
memset(alen,0,sizeof(alen));
while(~scanf("%d",&n))
{
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
int len=LIS(a,alen,n);
printf("%d\n",len);
}
}
【2】 二分查找+dp
替换思想,在我所现在有的递增子序列arr[len]里找第一个大于a[i]的,用a[i]替换它;
时间复杂度olog(n);
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define N 40005
int a[N];
int arr[N];
int UNDER_pos(int *dp,int l,int r,int key)
{
while(l<=r)
{
int mid=(l+r)/2;
if(dp[mid]>key)
{
r=mid-1;
}
else
{
l=mid+1;
}
}
return l;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(arr,0,sizeof(arr));
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
arr[1]=a[0];
int len=1;
for(int i=1; i<n; i++)
{
if(a[i]>arr[len])
{
arr[++len]=a[i];
}
else
{
int pos=UNDER_pos(arr,1,len,a[i]);
arr[pos]=a[i];
}
}
printf("%d\n",len);
}
}
【3】可以利用最长公共子序列LCS
现将给定的序列排序,然后,跟原序列求最长公共子序列;