最長不下降子序列 (3種做法)


最長不下降子序列,顧名思義就是總一組數據中找到一組最長數,這一組數據保證是b[0]<=b[1]<=b[2]......<=b[n-1]


最簡單的是樸素算法,還有dp的nlogn , stack nlogn   算法寶典416頁

具體思路不說了,忘了記得多看看書。

///stack優化 nlogn
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
const int maxn = 10000 + 10 ;
int a[maxn] , mystack[maxn] ;
int main()
{
    int n ;
    while(scanf("%d" , &n) != EOF)
    {
        memset(mystack , 0 , sizeof(mystack)) ;
        int temp ;
        int top = 0 ;
        mystack[0] = -1 ;
        for(int i = 1 ; i <= n ; i++) {
           scanf("%d" , &temp) ;
           if(mystack[top] < temp)
           {
               mystack[++top] = temp ;
           }
           else
           {
               int l = 1 , r = top , mid ;
               while(l <= r)
               {
                   mid  = (l + r) >> 1 ;
                   if(mystack[mid] < temp)
                   {
                       l = mid + 1;
                   }
                   else
                   {
                       r = mid - 1;
                   }
               }
               mystack[l] = temp ;
           }
        }
        printf("%d\n" , top) ;
    }
    return 0 ;
}

///初步優化nlogn
/*
 #include <iostream>
 #include <cstdio>
 #include <cstring>
 using namespace std ;
 const int maxn =  1000 + 10 ;
 int a[maxn] , mark[maxn] , len ;
 int tofind(int x)
 {
     int l = 1 , r = len , mid ;
     while(l <= r)
     {
         mid = (l + r) >> 1 ;
         if(mark[mid] < x)
            l = mid + 1;
         else
            r = mid - 1 ;
     }
     return l ;
 }
 int main()
 {
     int n ;
     while(scanf("%d" , &n) != EOF)
     {
         for(int i = 1 ; i <= n ; i++)
         {
             scanf("%d" , &a[i]) ;
         }

         len = 1 ;
         mark[len] = a[len] ;
         for(int i = 2 ; i <= n ; i++)
         {
             if(a[i] > mark[len])
             {
                 mark[++len] = a[i] ;
             }
             else
             {
               int findpos = tofind(a[i]) ;
               mark[findpos] = a[i] ;
             }
         }
         printf("%d\n" , len) ;
     }
     return 0 ;
 }
*/

///樸素算法
/*#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std ;
const int maxn = 10000 + 10 ;
int a[maxn] , mark[maxn] ;
int main()
{
    int n ;
    while(scanf("%d" ,&n) != EOF)
    {
        int maxlen = 1 ;
        for(int i = 0 ; i < n ; i++) {
            scanf("%d" , a + i) ;
            mark[i] = 1 ;
        }
        for(int i = n-1 ; i>= 0 ; i--)
        {
            for(int j = i + 1 ; j < n ; j++)
            {
                if(a[i] <= a[j])
                {
                    mark[i] = max(mark[i] , mark[j] + 1) ;
                    maxlen = max(maxlen , mark[i]) ;
                }
            }
        }
        printf("%d\n" , maxlen) ;
    }
}
*/


發佈了69 篇原創文章 · 獲贊 58 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章