模板题,复杂度O(nlogn),用到的栈的思想。
但是注意,最终栈中的数据是乱序的。。。
如 1 5 6 2 3 4
栈中依次为1 5 6,读2后栈中为1 2 6,此时最长仍为3,读3后为1 2 3,接着为1 2 3 4,最终结果为4(这个是恰巧是最终求得序列,但大多数情况不是的)
lower_bound(s,s+top,a[i]) 返回一个非递减序列[s, s+top)中的第一个大于等于值a[i]的位置
#include<iostream> #include<algorithm> using namespace std; int a[1001],s[1001]; int main() { int n,i; cin>>n; for (i=0;i<n;i++) cin>>a[i]; int top=0,*j; s[top]=a[0]; for (i=1;i<n;i++) { if (a[i]>s[top]) s[++top]=a[i]; else { //假如比栈顶值小则在栈中用二分法找第一个>=a[i]的值并替换掉 //这样使序列的扩展性更强。 j=lower_bound(s,s+top,a[i]);//本题之精华 *j=a[i]; } } cout<<top+1; return 0; }
复杂度为O(n^2)的代码:
#include<iostream> #include<algorithm> using namespace std; int a[1001],dp[1001]={0}; int main() { int n,i,j,ans; cin>>n; for (i=0;i<n;i++) cin>>a[i]; ans=0; for (i=0;i<n;i++)//序列到i为止 { dp[i]=1; for (j=0;j<i;j++) if (a[j]<a[i])//在0~i-1为止的序列中找最长的序列(并加上i) dp[i]=max(dp[i],dp[j]+1); ans=max(ans,dp[i]); } cout<<ans; return 0; }