例題
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 下...