【轉】關於LIS和一類可以用樹狀數組最佳化的DP 預備知識

來源:互聯網
上載者:User

標籤:about   範圍   定義   zoj   ram   a10   推出   先來   problem   

原文連結 http://www.cnblogs.com/liu-runda/p/6193690.html

 

  1. 預備知識

    DP(Dynamic Programming):一種以無後效性的狀態轉移為基礎的演算法,我們可以將其不嚴謹地先理解為遞推。例如斐波那契數列的遞推求法可以不嚴謹地認為是DP。當然DP的狀態也可以是二維/三維的,某一維的含義也不僅僅是指某個數列的第幾項。

    樹狀數組(BIT or fenwick tree):一種高效地動態維護一個序列並動態求取首碼和的資料結構。修改某個元素/求一次首碼和的時間複雜度均為O(logn)

  2 LIS

    好了現在假設你們都會打樹狀數組了(如果不會的話,baidu一發吧!順便把線段樹也自學了吧!如果學不會樹狀數組只把線段樹自學了也成因為好像並沒有樹狀數組能幹而線段樹榦不了的事情),讓我們做一道例題練習一下吧!。

    給出一個長度為n的序列,求LIS長度(LIS,longest increasing sequence,最長上升子序列,子序列定義為從原序列取出的一些未必相鄰但保持原先的相對順序的數,上升子序列滿足子序列中前一個數嚴格小於後面的數)

    50% n<=5000,100% n<=50000

    50%的資料其實並沒有用到樹狀數組。

    O(n^2)的LIS演算法:定義f[i]為強制以第i項結尾時的LIS長度。那麼從1到n依次求出每個f[i],f[i]可以由f[1...i-1]推出。

    好了,現在假設你們都會寫50分了。我們考慮把演算法最佳化到能跑50000

    首先離散化,將原先的數字對應到1-tot(tot為出現過的數值種類),例如10,10,20,15變成1,1,3,2

    那麼我們定義g[i]為以數值i結尾的LIS長度,並從左向右掃描原數組,同時維護g數組。掃描1,1,3,2時,g數組變化如下:(未出現的項的值為0)

      a.g[1]=1

      b.g[1]=1

      c.g[1]=1,g[3]=2

      d.g[1]=1,g[2]=2,g[3]=2

    YY一下我們怎樣用g數組完成DP。

    接下來我們需要一種資料結構支援單點修改(只增不減)和首碼最大值查詢。

    首先來一個逗比分塊寫法維護g數組:將g均分成sz塊,維護每一塊的最大值。修改可以O(1)完成,首碼最大值查詢可以將整塊整塊的部分用每一塊的最大值求,零散部分暴力掃一遍。sz取在sqrt(n)附近的時候效率最高。總時間複雜度O(nsqrt(n)),自信AC。

    如果n<=233333?

    我們可以樹狀數組維護g數組。原始的樹狀數組改造後可以支援單點修改(只增不減)和首碼最大值查詢。把樹狀數組的加法換成取最大值,YY一下。

    最後整個g數組的最大值就是答案。

  3. LCS

    好了,現在假設你們都會nlogn的LIS,讓我們來一道例題練習一下吧!

    uva10635 Prince and Princess(資料範圍是我口胡的)

    給出兩個1~n的排列(一個1~n的排列中,1-n每個數字出現一次,不重複出現),求LCS(最長公用子序列)長度。50%的資料保證第一個排列為1,2,3,...n按順序遞增的。

    n<=233333

    50%資料是第二個排列的LIS。很好50分到手。

    下面設想一下,把數字重新編號,LCS長度不變。例如,兩個序列為1,2,3; 3,2,1.那麼a,b,c;c,b,a的答案是和它一樣的。那麼把數字編號為數字也是可以的。

    例如這兩個資料:

    (1)

    4

    1 2 3 4

    2 3 4 1

    (2)

    4

    4 3 2 1

    3 2 1 4

    它們的答案是相同的。因為在求解LCS時,我們只關注兩個序列某兩個下標處的數值是否相同,重新編號沒有改變“對應下標位置的數相同”的資訊。

    那麼我們把一個序列重編號為1,2,3...n,對另一個序列也用同樣的對應關係重編號(即把第二個序列中每個數改成這個數在第一個序列中出現的下標),跑LIS,自信AC。

  4. more about LCS

    接下來我們分兵奇襲,用另一條思路得出剛才例題lcs的另一個nlogn做法。

    首先自己yy一下LCS的O(n^2)演算法。它的狀態定義為f[i][j]表示允許使用第一個序列的前i個元素,第二個序列的前j個元素(其中第i個,第j個元素不要求必須使用)

    接下來我們修改狀態定義(這種事情在最佳化DP時需要經常幹)使得它能最佳化到nlogn.

    新的狀態中,f[i][j]表示允許使用第一個序列的前i個元素,第二個序列的前j個元素(其中第一個序列第i個元素不必須使用,第二個序列第j個元素必須使用

    於是我們把原先的DP改成分層的過程,考慮從f[i-1][]求出f[i][],那麼這兩個數組最多有一個位置不同(只有以第一個序列的第i個元素結尾的答案會發生改變)。

    那麼我們動態維護這個數組就可以了。假如第一個序列中第i個元素在第二個序列中出現在第k個位置,那麼修改f[k]即可(這裡已經幹掉了第一維)。

    f[k]等於什嗎?等於f[1...k-1]的最大值+1,因為在LCS中前一項一定是第二個序列前面k-1的項中的一項(如果已經是第一項,沒有前一項?邊界自己處理一下我就不(懶得)寫了)。

    於是還是樹狀數組首碼最大值,只增不減的單點修改。

    事實上,這個演算法只要保證匹配上的位置不多即可。因此1-n每個數字出現5次也是能寫的。

    http://www.lydsy.com/JudgeOnline/problem.php?id=1264 bzoj1264基因匹配

  5。more about BIT&DP

    二維樹狀數組也是可以拿來最佳化DP的 http://www.lydsy.com/JudgeOnline/problem.php?id=3594  方伯伯的玉米田

    座標系可以轉...http://www.lydsy.com/JudgeOnline/problem.php?id=2131  免費餡餅

    和樹狀數組沒關係的傻逼題 http://www.lydsy.com/JudgeOnline/problem.php?id=4300

    2016.12.31update:終於想到了一道noip題NOIP2012擺花 http://cogs.pro/cogs/problem/problem.php?pid=1270

  6. 鞏固練習一下LIS

    http://www.lydsy.com/JudgeOnline/problem.php?id=3173

    http://www.lydsy.com/JudgeOnline/problem.php?id=4660

由於我太弱,所以這裡的例題比較少...虛心求dalao們在評論區提供例題。

【轉】關於LIS和一類可以用樹狀數組最佳化的DP 預備知識

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.