【解析】
举个例子吧,比如一个数组a[9]={0,1,2,5,3,6,8,7,9}这样一个数组,a[0]是不参与运算的啊,这里我是为了好写,叫你求最长的上升子序列,其实我们可以这么看,定义两个数组b[10],c[10],其实就是这么两个过程,先把a[1]给了b[1],此时b[1]为1,然后c[1]也为1,表示上升子序列长度为1的,元素为1,之后把a[2]给b[2],此时b[2]为2,b[2]>b[1]所以此时上升子序列长度变二c[2]也我为2,之后呢a[3]给b[3],前者显然大于后者所以继续,直到a[4]的时候我们发现a[4]是小于a[3]的,我们其实可以这么想,如果保持上升子序列长度不变,是不是这个序列中前面元素越小,后面才有可能继续变大,不如你一个序列可能是1,2,3,5,4,6那么我们应该怎么选择?肯定是选1,2,3,4,6这个作为最长子序列,而不会选择1,2,3,5是吧就是把小的元素尽量替换掉插进去。此刻替换掉我们就需要有一个二分法来求下界了,因为c这个数组是有序的所以可以二分法,注意二分法必须是有序的序列。求下界的话如果存在相同的就返回出现第一次出现那个元素的下标,没有就返回一个下标插入元素使整个序列任然是有序的。在大佬那里学到了这个算法。
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
int a[100]={0,1,2,5,3,6,8,7,9},b[100],len;
int facs(int i)
{
int left=0;int right=len;
int mid;
while(left<right)
{
mid=left+(right-left)/2;
if(b[mid]>a[i])
right=mid;//往左边找
else
left=mid+1;//往后面找
}
return left;
}
int main()
{
b[1]=a[1];
len=1;
int k;
for(int i=2;i<=8;i++)
{
if(a[i]>b[len])
{
b[++len]=a[i];
}
else
{
k=facs(i);
b[k]=a[i];
}
}
printf("%d\n",len);
return 0;
}