420K |
125MS |
GCC |
596B |
2009-01-11 00:56:04 |
技巧:设置一个数组a[i]
存放所有长度为i的上升子序列中最小的末元素值,比如说只有两个长度为3的上升子序列123和124,那么a[3]中存放的就是3(末元素3<4)
那么当来一个新数data时,如果它的值大于最长长度的末元素的值(即a[ans]),则ans++;且a[ans]=data;
否则,通过二分查找(数组a中的元素为递增),将最接近data且大于data的那个元素更新为data。
代码如下:
Code
#include<stdio.h>
int a[40000],data,ans;
void process()
{
int num,i,j,left,right,middle;
scanf("%d",&num);
ans=0;
while(num--)
{
scanf("%d",&data);
if(ans == 0){
a[1]=data;
ans++;
}
else{
if(data>a[ans]){
ans++;
a[ans]=data;
}
else{
left=0;right=ans;
while(left<right){
middle=(left+right)/2;
if(a[middle]>=data) right=middle;
else if(a[middle]<data) left=middle+1;
}
if(a[right]>data)
a[right]=data;
}
}
}
printf("%d\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
process();
}
}