dp——O(nlogn)求LIS

閒話

衆所周知,求LIS最簡單的方法是O(n^2)的,但是有的題目會卡這個做法,這時我們就需要考慮優化了。

算法描述

我們定義一個數組d[i]爲表示長度爲i的上升子序列的最小末尾元素。

然後我們每次往裏面插入數字的時候考慮是否大於最後一個元素,如果大於接直接插入,否則的話找到前面比他大的第一個元素,並且把它替換掉,最後的數組大小就是LIS的長度。

舉例闡述

下面模擬一組數據:2,5,4,3,1,6

初始化len=0表示LIS長度

1.插入2,d數組裏面只有2,len=1,                                                                                  d : 2

2.插入5,因爲5比2大,直接插入,len=2,                                                                          d : 2 5

3.插入4,前面第一個比它大的元素爲5,把5替換掉,長度不變, len=2                              d : 2 4

4.插入3,前面第一個比他大的元素爲4,   把4替換掉,   長度不變,len=2                               d : 2 3

5.插入1,前面第一個比他大的元素爲2,   把2替換掉,   長度不變,len=2                               d : 1 3

6.插入6,前面的數都比它小,因此我們可以直接插入, len = 3                                            d : 1 3 6

至此LIS的長度已經求出來了,爲len=3.

我們很容易發現d數組中的元素是遞增的,因此我們可以二分去找插入它的位置(當前面有比當前數大的值),

這樣時間複雜度就變成了O(nlogn)

就不給代碼了,也比較好實現。

應用部分:

1.就是直接給你n=1e6的序列,讓你求他的LIS長度,(模板題)

2.通常情況下因爲d數組的性質,當範圍比較小時,把所有可能狀壓一下,然後結合各種題型考你。

給個經典例題(數位dp+O(nlogn)求LIS+狀壓):https://vjudge.net/problem/HDU-4352

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章