「網絡流24題」最長不下降子序列問題
傳送門:>Here<
題意:
給定正整數序列$x_1,...,x_n$
(1)計算其最長不下降子序列的長度s。
(2)計算從給定的序列中最多可取出多少個長度為s的不下降子序列。
(3)如果允許在取出的序列中多次使用$x_1$和$x_n$,則從給定序列中最多可取出多少個長度為$s$的不下降子序列。
思路分析
題意首先就很坑:註意第二問中的取出二字,意味著一個數字最多只能存在於一個LIS中。所以才會有第三問的假設
第一問很簡單,直接暴力$O(n^2)$就好了
後面的兩問需要借助於網絡流。很容易想到:令S到T的任意一條路徑表示一個LIS,並且設邊的容量為1。這樣的話最大流也就是能取出的LIS數量(和二分圖匹配原理一樣,一個點不會被用兩次)
因此我們還是需要像二分圖匹配一樣拆點,每個點拆為兩個。然後令$f[i]=1$的點連源點,$f[i]=maxs$的點連匯點。然後我們最初的想法是f值連續遞增的並且能組成不下降子序列的兩數之間連邊即可。但這裏情況也許不同了,想象一個類似$5,4,3,2,1$這樣完全下降的序列,這樣的話兩部分的點之間不能連任何邊,最大流跑出來是0。然而由於LIS長度為1,很明顯有5種取法!
因此我們考慮,被拆的兩個點自己連到自己,並且遞增的邊反過來連,就能解決問題。這樣表達不清晰,下面詳細闡述如何連邊:
首先原序列做LIS,其中$f[i]$表示以$a[i]$為結尾的LIS的最大長度。對序列的每一個數進行拆點,也就是分為$X_i, Y_i$。我們要讓S到T的每一條路徑都是一個LIS,因此若$f[i]=1$,則$X_i$的點連接源點,$f[i]=maxs$則$Y_i$連接匯點。其中對於每一個數字,連接有向邊$(X_i, Y_i)$。並且在做LIS的過程中,若發現一對數字滿足$a[j]<=a[i] 且 f[j]+1=f[i]$,則連有向邊$(Y_j, X_i)$。最後做最大流即可
Code
細節題
「網絡流24題」最長不下降子序列問題