模板题,复杂度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;
}