http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1134
普通dp的时间复杂度是O(n2),肯定会超时,采用dp+二分的方法,可以优化到O(nlogn)。
例如上面的序列: i为序列下标
i=0 d[1]=5
i=1 d[1]=1 (1<d[1])
i=2 d[2]=6 (6>d[1])
i=3 d[3]=8 (8>d[2])
i=4 d[2]=2 (2<d[2])
i=5 d[3]=4 (4<d[3])
i=6 d[4]=5 (5>d[3])
i=7 d[5]=10 (10>d[4])
最终得到 最长序列为 5。*
#include<iostream>
#include<stdio.h>
#define max1 50005
using namespace std;
int d[max1]; //d[i]表示长度为i时,值最小的元素
int main()
{
int n,val,len=0;
cin>>n;
for(int x=0;x<n;x++)
{
scanf("%d",&val); //val为序列元素
if(x==0) d[++len]=val;
if(val>d[len]) d[++len]=val; //如果大于d[len],直接更新len和d[len]
else
{
int left=1,right=len;
while(left<=right) //二分查找
{
int mid=(left+right)/2;
if(d[mid]<val)
left=mid+1;
else
right=mid-1;
}
d[left]=val; //找到第一个大于val的元素位置
}
}
cout<<len;
}