O(nlog(n))的算法,网上讲解有很多,我就不在这里献丑了,直接上模板
该模板计算从1到n的LIS,p[]为存放数列的数组
最长上升子序列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int LIS(int n) { int l,r,m,i,tail = 0; for ( dp[ ++ tail ] = p[ 1 ],i = 2 ; i <= n ; ++ i ) { if ( dp[ tail ] < p[ i ] ) { dp[ ++ tail ] = p[ i ]; continue; } for ( m=((r=tail)+(l=1)>>1) ; l < r ; m=(l+r)>>1 ) if ( dp[ m ] < p[ i ] ) l = m+1; else r = m; dp[ m ] = p[ i ]; } return tail; }
O(n^2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int LIS(int n) { int ans=0 ; for(int i=1 ;i<=n ;i++) { dp[i]=1 ; for(int j=1 ;j<i ;j++) if(a[j]<a[i] && dp[j]+1>dp[i]) dp[i]=dp[j]+1 ; ans=max(ans,dp[i]) ; } return ans ; }
最长非下降子序列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int LIS(int n) { int l,r,m,i,tail = 0; for ( dp[ ++ tail ] = p[ 1 ],i = 2 ; i <= n ; ++ i ) { if ( dp[ tail ] <= p[ i ] ) { dp[ ++ tail ] = p[ i ]; continue; } for ( m=((r=tail)+(l=1)>>1) ; l < r ; m=(l+r)>>1 ) if ( dp[ m ] <= p[ i ] ) l = m+1; else r = m; dp[ m ] = p[ i ]; } return tail; }