這裏要講的是導彈攔截的第二問,即:給定一個序列,求它的最小鏈覆蓋。
經典的做法是對每兩個可以搞到一起的點連邊,用之前講的h-k算法求一遍最大匹配,但是,這種方法的複雜度可能會退化到O(n^2)。一種有效的解法是利用dilworth定理求一遍最長反鏈,其複雜度爲O(nlog(n))。
先介紹一下偏序關係:對集合A中的兩個元素,引入一個序的概念,設爲R,很明顯,要麼R(x,y),要麼R(y,x),要麼x,y之間根本沒有序。若對一個集合A和定義在A之上的序R,恆有:(1)R(x,x)(自反性);(2)若R(x,y)且R(y,x)則x=y(反對稱性);(3)若R(x,y)且R(y,z),則有R(x,z)(傳遞性),則稱A爲偏序集,記爲(A,R)。
對一個偏序集(A,R),若R(x,y)或R(y,x),則稱x,y是可比的,否則就是不可比的。
一個鏈是偏序集的一個子集,它的任意兩個元素都是可比的。
一個反鏈是偏序集的一個子集,它的任意兩個元素都是不可比的。
很明顯,導彈攔截中給出的序列對於R(i>j且ai<aj)是一個偏序集。題目所求的就是他的最小鏈覆蓋。
dilworth定理:對一個有限偏序集A,它的最小鏈覆蓋=最長反鏈。證明自己翻書。
於是,原問題就得到了一個完美的解決:求出原序列的的最長上升子序列,即爲所求的答案。
總之,在有限偏序集中,有:
(1)最長鏈=最小反鏈覆蓋
(2)最長反鏈=最小鏈覆蓋
再附一個鏈接:http://blog.csdn.net/emoizhang/article/details/8009123,他講了一下證明,不過他把鏈和反鏈的概念弄混了,不知道現在改過來沒有。對他的證明只要看思路就行了。
推薦例題:poj3636
BY QW
轉載請註明出處