• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

            最近在做單調(diào)隊(duì)列,發(fā)現(xiàn)了最長上升子序列O(nlogn)的求法也有利用單調(diào)隊(duì)列的思想。

                最長遞增子序列問題:在一列數(shù)中尋找一些數(shù),這些數(shù)滿足:任意兩個數(shù)a[i]和a[j],若i<j,必有a[i]<a[j],這樣最長的子序列稱為最長遞增子序列。

               設(shè)dp[i]表示以i為結(jié)尾的最長遞增子序列的長度,則狀態(tài)轉(zhuǎn)移方程為:

            dp[i] = max{dp[j]+1}, 1<=j<i,a[j]<a[i].

               這樣簡單的復(fù)雜度為O(n^2),其實(shí)還有更好的方法。

               考慮兩個數(shù)a[x]和a[y],x<y且a[x]<a[y],且dp[x]=dp[y],當(dāng)a[t]要選擇時,到底取哪一個構(gòu)成最優(yōu)的呢?顯然選取a[x]更有潛力,因?yàn)榭赡艽嬖赼[x]<a[z]<a[y],這樣a[t]可以獲得更優(yōu)的值。在這里給我們一個啟示,當(dāng)dp[t]一樣時,盡量選擇更小的a[x].

                按dp[t]=k來分類,只需保留dp[t]=k的所有a[t]中的最小值,設(shè)d[k]記錄這個值,d[k]=min{a[t],dp[t]=k}。

                這時注意到d的兩個特點(diǎn)(重要):

            1. d[k]在計(jì)算過程中單調(diào)不升;           

            2. d數(shù)組是有序的,d[1]<d[2]<..d[n]。

                利用這兩個性質(zhì),可以很方便的求解:

            1. 設(shè)當(dāng)前已求出的最長上升子序列的長度為len(初始時為1),每次讀入一個新元素x:

            2. 若x>d[len],則直接加入到d的末尾,且len++;(利用性質(zhì)2)

               否則,在d中二分查找,找到第一個比x小的數(shù)d[k],并d[k+1]=x,在這里x<=d[k+1]一定成立(性質(zhì)1,2)。

             

            1. /** 
            2. 最長遞增子序列O(nlogn)算法: 
            3. 狀態(tài)轉(zhuǎn)移方程:f[i] = max{f[i],f[j]+1},1<=j<i,a[j]<a[i]. 
            4. 分析:加入x<y,f[x]>=f[y],則x相對于y更有潛力。 
            5. 首先根據(jù)f[]值分類,記錄滿足f[t]=k的最小的值a[t],記d[k]=min{a[t]},f[t]=k. 
            6.     1.發(fā)現(xiàn)d[k]在計(jì)算過程中單調(diào)不上升 
            7.     2.d[1]<d[2]<...<d[k] (反證) 1 2 3 8 4 7 
            8. 解法: 
            9. 1. 設(shè)當(dāng)前最長遞增子序列為len,考慮元素a[i]; 
            10. 2. 若d[len]<a[i],則len++,并將d[len]=a[i]; 
            11.    否則,在d[0-len]中二分查找,找到第一個比它小的元素d[k],并d[k+1]=a[i].() 
            12. */  
            13. #include <iostream>  
            14. #include <cstdio>  
            15. #include <cstring>  
            16. using namespace std;  
            17. const int N = 41000;  
            18. int a[N];       //a[i] 原始數(shù)據(jù)  
            19. int d[N];       //d[i] 長度為i的遞增子序列的最小值  
            20.   
            21. int BinSearch(int key, int* d, int low, int high)  
            22. {  
            23.     while(low<=high)  
            24.     {  
            25.         int mid = (low+high)>>1;  
            26.         if(key>d[mid] && key<=d[mid+1])  
            27.             return mid;  
            28.         else if(key>d[mid])  
            29.             low = mid+1;  
            30.         else  
            31.             high = mid-1;  
            32.     }  
            33.     return 0;  
            34. }  
            35.   
            36. int LIS(int* a, int n, int* d)  
            37. {  
            38.     int i,j;  
            39.     d[1] = a[1];  
            40.     int len = 1;        //遞增子序列長度  
            41.     for(i = 2; i <= n; i++)  
            42.     {  
            43.         if(d[len]<a[i])  
            44.             j = ++len;  
            45.         else  
            46.             j = BinSearch(a[i],d,1,len) + 1;  
            47.         d[j] = a[i];  
            48.     }  
            49.     return len;  
            50. }  
            51.   
            52. int main()  
            53. {  
            54.     int t;  
            55.     int p;  
            56.     scanf("%d",&t);  
            57.     while(t--)  
            58.     {  
            59.         scanf("%d",&p);  
            60.         for(int i = 1; i <= p; i++)  
            61.             scanf("%d",&a[i]);  
            62.         printf("%d\n",LIS(a,p,d));  
            63.     }  
            64.     return 0;  
            65. }  

             

            Feedback

            # re: 最長上升子序列 O(nlogn)解法 (轉(zhuǎn))  回復(fù)  更多評論   

            2014-10-21 14:46 by 無憂
            寫的不錯 謝謝
            久久久国产打桩机| 国产 亚洲 欧美 另类 久久| 色综合色天天久久婷婷基地| 一本色道久久综合狠狠躁| 久久精品综合一区二区三区| 91久久精品国产免费直播| 青青草原综合久久| 99久久免费只有精品国产| 99久久国产综合精品网成人影院 | 久久99久久99小草精品免视看| 日韩人妻无码精品久久免费一| 婷婷伊人久久大香线蕉AV| 无码国内精品久久人妻| 久久国产精品成人片免费| 国产Av激情久久无码天堂| 久久综合丝袜日本网| 久久精品人妻一区二区三区| 老司机午夜网站国内精品久久久久久久久 | 久久综合伊人77777麻豆| 国产精品成人久久久| 少妇久久久久久久久久| 91视频国产91久久久| AAA级久久久精品无码区| 亚洲国产精品一区二区三区久久| 一本久久知道综合久久| 国产精品久久久久久久| 久久精品无码一区二区日韩AV| 国产99久久久国产精品小说| 久久国产精品99国产精| 久久人人爽人人爽人人片AV东京热| 久久天天躁夜夜躁狠狠躁2022| 久久精品国产亚洲麻豆| 久久这里的只有是精品23| 久久久久无码精品国产不卡| 久久国产精品国语对白| 久久精品国产亚洲AV无码麻豆| 久久久久国产一级毛片高清板| 日韩av无码久久精品免费| 欧美激情精品久久久久久久 | 精品久久久久久无码专区| 欧美与黑人午夜性猛交久久久|