问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7....an,求它的一个子序列(设为s1,s2,...sn),使得这个子序列满足这样的性质,s1<s2<s3<...<sn并且这个子序列的长度最长。输出这个最长的长度。(为了简化该类问题,我们将诸如最长下降子序列及最长不上升子序列等问题都看成同一个问题,其实仔细思考就会发现,这其实只是<符号定义上的问题,并不影响问题的实质)
下面是模板:
int lis(int a[],int n) { int i,j,ans=1,m=0,*dp=new int[n+1]; dp[0]=1; for(i=1;i<n;i++) { m=0; for(j=0;j<i;j++) //可以改进一下再求出这个子序列的第一和最后一个元素 if(dp[j]>m&&a[j]<a[i]) m=dp[j]; dp[i]=m+1; if(dp[i]>ans) ans=dp[i];//1 7 3 5 9 4 8 } return ans; }
int a[1000],c[1000],len; int bsearch(int l,int r,int x) { if(l==r) return l; int p,mid=(l+r)/2; if(c[mid]<x) return p=bsearch(mid+1,len,x); else return p=bsearch(l,mid,x); } int lis(int n) { int i,j; len=0; c[0]=-100000000; for(i=0; i<n; i++) { if(a[i]>c[len]) j=++len; else j=bsearch(1,len,a[i]); c[j]=a[i]; } return len; }