LIS的优化算法O(n log n)

LIS的nlogn的优化:
LIS的优化说白了实际上是贪心算法,好比说让你求一个最长上升子序列把,一块儿走一遍。ios

好比说(4, 2, 3, 1, 2,3,5)这个序列,求他的最长上升子序列,那么来看,若是求最长的上升序列,那么按照贪心,应该最可能的让该序列的元素总体变小,以即可以加入更多的元素。
如今开辟一个新的数组,arr[ 10 ], { .......} --> 这个是他的空间 ,如今开始模拟贪心算法求解最长上升子序列,第一个数是4,先加进去,那么为{ 4 }再来看下一个数2,它比4小,因此若是他与4替换是否是能够让目前子序列(他这一个元素组成的子序列)变得更小,更方便之后元素的加入呢?是的。因此如今为{ 2 } 再来看他的下一个元素3,他要比2大,因此呢加在他的后面,{ 2, 3}
再看下一个元素是1,它比3要小,因此呢为了保证子序列总体尽量的小(以即可以加入更多的元素),从目前的序列中查找出第一个比他大的数替换掉,那么就变成了{ 1, 3},继续。。 下一个数是2,那么序列变为{ 1,2},再下一个数为3,那么序列为{1,2,3},在下一个数为5,那么序列为{1,2,3,5},完。 目前序列里又4个元素,因此他的最长子序列的个数为4,可是这个序列是一个伪序列,里面的元素,并非真正的最长上升子序列,而仅仅和最长上升子序列的个数同样。由于查找的时候用的二分查找,因此时间复杂度为o(nlogn)。算法

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;  6 
 7 int main(){  8     int arr[500],n,dp[500];  9     scanf("%d",&n); 10     for( int i=1; i<=n; i++ ){ 11         scanf("%d",&arr[i]); 12  } 13     int k=1; 14     dp[k]=arr[1]; 15     for( int i=2; i<=n; i++ ){ 16         if(arr[i]>dp[k]) dp[++k]=arr[i]; 17         else *lower_bound(dp+1,dp+1+k,arr[i])=arr[i]; 18  } 19     printf("%d\n",k); 20     return 0; 21 }
相关文章
相关标签/搜索