1. 程式人生 > >「網絡流24題」最長不下降子序列問題

「網絡流24題」最長不下降子序列問題

計算 二分圖匹配 原理 最長 span 情況 遞增 mic ros

傳送門:>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題」最長不下降子序列問題