1. 程式人生 > >LIS的優化算法O(n log n)

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

class namespace name 優化算法 貪心算法 amp 個數 方便 成了

LIS的nlogn的優化:
LIS的優化說白了其實是貪心算法,比如說讓你求一個最長上升子序列把,一起走一遍。

比如說(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 }

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