求兩個不相交的最長不降子串行

2021-09-24 21:14:39 字數 2847 閱讀 4156

例題

comet oj contest #6b 雙倍快樂:

題意:

comet: 求序列 a 中的兩個不相交的不下降子串行使得他們的元素和的和最大,子串行可以為空。

hdu : 一棵樹有若干蘋果,蘋果有個甜度、高度,要求選兩個的吃蘋果序列的甜度與高度均單調不減。求吃最大的蘋果數。

(說人話:給定n個蘋果,按照高度排序後,對甜度求兩個最長的不相交的lis。)

資料:
comet :2≤n≤500,1≤a≤1e5

hdu :1 ≤ t ≤ 48,1≤n≤1000,1≤a≤1e9

注 1:序列不下降的定義是不存在 la_r

注 2:兩個子串行不相交的定義是:不存在元素x既在第乙個子串行中也在第二個子串行中

思路:
方法一:(通用方法)

最直觀的方法:費用流。

1. 兩個序列的長度和(總序列和)最大,視作從超級源點出發的流量為2的費用流,建負權邊。

2. 每個物品只能取一次,則拆點為 入點 和 出點,中間建容量為1,費用為-1(或者物品值)的邊。

3. 源點向每個入點建容量為1,費用為0的邊,表示每個點都可作為序列的首項;

每個出點向匯點建容量為1,費用為0的邊,表示每個點都可作為序列的末項。

4. 從權值較小的物品向權值較大的物品建邊,容量為1,費用為0。

5. 跑出費用流後,對 總最小費用 取反 就是答案。(hdu裡面用spfa需要棧優化,佇列會tle)

方法二:(針對comet資料小一點)

二維的dp,o(n^3)的複雜度。(後面還有優化)

1. dp[i][j]表示 第乙個子串行末尾值為i 和 第二個子串行末尾值為j 時的最大長度(序列和)。

由於資料規模問題(hdu),需要對序列離散化。

2. 可以考慮對第k個元素來說,可以放到第乙個串後面更新dp[k][j],也可以放到第二個串後面更新dp[i][k]。

3. 那麼轉移方程:(+1是求長度,+a[k]是求和)

dp[k][j] = max(dp[k][j], dp[i][j] + a[k])

dp[i][k] = max(dp[i][k], dp[i][j] + a[k])

4.整體就是個o(n^3)的dp了

方法三:(hdu資料大一點)

二維dp用樹狀陣列優化,o(n^2logn)的複雜度。(線段樹之類的也行,這個問題樹狀陣列寫起來很簡潔--學到了)

1. 還是dp[i][j]表示 第乙個子串行末尾為i 和 第二個子串行末尾為j 時的最大長度(序列和)。

(離散化後)

2. 其中某個dp[i][j]的值是從小於值j的最大值轉移過來的:單點修改,字首最大值查詢。

即 dp[i][j] = max(dp[i][k])+a[k] (+1是求長度,+a[i]是求和)

3. 由於兩個序列是等價的,因此dp[i][j]=dp[j][i],在更新時候只需要按照行更新,即只需要更新i行和j行就行。

4. 注意到dp[i]的值是單調不減的。每次修改,都可以用樹狀陣列向上傳遞更新。(如果dp[i]的值會變小,就無法向上傳遞更新了。)

查詢 滿足k <= i 剛好是字首查詢。

**:(hdu 5406的方法三)
#include 

求最長不降子串行

試題描述 給定乙個整數序列a1 a2 an,求這個序列中的乙個子串行 不一定連續 使得這個序列中的元素嚴格遞增,並且這個序列最長。輸入第一行,乙個整數n。第二行,n個整數,a1 a2.an。輸出一行,乙個整數,表示你所求的最大長度。輸入示例 41 3 2 4 輸出示例 3其他說明 n 1000,給定...

C 飛彈攔截 求最長不降子串行

c 飛彈攔截 求最長不降子串行 時間限制 1 sec 記憶體限制 128 mb 題目描述 某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在...

求最長不降子串行(動態規劃)

求最長不下降子串行 動態規劃 狀態轉移方程 length i 1 length j j為data i data j 的情況下能使length j 取到最大的值 初始情況length 1 1 且length 0 0,這樣求出來的length j 才可以取到0 include int data 15 下...