網路流24題 最長遞增子串行

2022-05-03 09:27:10 字數 2740 閱讀 7557

★★★☆   輸入檔案:alis.in輸出檔案:alis.out簡單對比

時間限制:1 s   記憶體限制:128 mb

«問題描述:

給定正整數序列x1,..., xn。

(1)計算其最長遞增子串行的長度s。

(2)計算從給定的序列中最多可取出多少個長度為s的遞增子串行。

(3)如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長

度為s的遞增子串行。

注意:這裡的最長遞增子串行即最長不下降子串行!!!

«程式設計任務:

設計有效演算法完成(1)(2)(3)提出的計算任務。

«資料輸入:

由檔案alis.in提供輸入資料。檔案第1 行有1個正整數n(n<=500),表示給定序列的長度。接

下來的1 行有n個正整數x1,..., xn。

«結果輸出:

程式執行結束時,將任務(1)(2)(3)的解答輸出到檔案alis.out中。第1 行是最長

遞增子串行的長度s。第2行是可取出的長度為s 的遞增子串行個數。第3行是允許在取出

的序列中多次使用x1和xn時可取出的長度為s 的遞增子串行個數。

輸入檔案示例 輸出檔案示例

alis.in

43 6 2 5

alis.out22

3【問題分析】

第一問是lis,動態規劃求解,第二問和第三問用網路最大流解決。

【建模方法】

首先動態規劃求出f[i],表示以第i位為開頭的最長上公升序列的長度,求出最長上公升序列長度k。

1、把序列每位i拆成兩個點和,從到連線一條容量為1的有向邊。

2、建立附加源s和匯t,如果序列第i位有f[i]=k,從s到連線一條容量為1的有向邊。

3、如果f[i]=1,從到t連線一條容量為1的有向邊。

4、如果j>i且a[i] < a[j]且f[j]+1=f[i],從到連線一條容量為1的有向邊。

求網路最大流,就是第二問的結果。把邊(<1.a>,<1.b>)(,)(s,<1.a>)(,t)這四條邊的容量修改為無窮大,再求一次網路最大流,就是第三問結果。

【建模分析】

上述建模方法是應用了一種分層圖的思想,把圖每個頂點i按照f[i]的不同分為了若干層,這樣圖中從s出發到t的任何一條路徑都是乙個滿足條件的最長上公升子串行。由於序列中每個點要不可重複地取出,需要把每個點拆分成兩個點。單位網路的最大流就是增廣路的條數,所以最大流量就是第二問結果。第三問特殊地要求x1和xn可以重複使用,只需取消這兩個點相關邊的流量限制,求網路最大流即可。

ps:任務3若能取出無限多的序列,則輸出任務2的答案

//資料略坑

#include

#include

#include

#define

setfile

(name

)freopen

(#name".in","r",stdin);freopen(#name".out","w",stdout);

using

namespace

std;

const

intn

=1005

;const

intinf

=1e9

;struct

edgee[

n*n*

2];inttot=1

,head[n

];intn,

s,t,

k,ans,a[

n],f[

n],dis[n],

q[n*

n*2];

inline

intread

()while(ch

>=

'0'&&

ch<=

'9')

returnx*

f;}inline

void

add(

intx

,inty,

intz

)inline

bool

bfs()}}

return0;

}int

dfs(

intx

,intf)

}if(!used

)dis[x

]=-1

;return

used;}

inline

intdinic

()inline

void

dp()}}

k=*max_element(f

+1,f

+n+1

);}void

init

()void()}

}}inline

void

work

()ans

=dinic

();printf

("%d\n"

,ans

);();

for(

inti=1

;i<=n;

i++)

intlastans

=ans

;ans

=dinic

();if

(ans

>

inf)

printf

("%d\n"

,lastans

);else

printf

("%d\n"

,ans);}

intmain

()

網路流 24 題 最長遞增子串行

1 dp求一遍 2 所有點拆成入點和出點,對於沒個f i 1的1點連源點,每個f i ans1的點連匯點,每個點的入點和出點再連一條邊,所有容量為1,求一遍最大流。2 1和n可以用多次,所以對於點1和點n,入點和出的連邊的容量變為inf,如果需要連源點或匯點那麼容量也變為n,其餘容量為1,求一遍最大...

網路流24題 最長遞增子串行

給定正整數序列x1,xn。1 計算其最長遞增子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的遞增子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的遞增子串行。設計有效演算法完成 1 2 3 提出的計算任務 第1 行有1個正整數n n 500...

網路流24題6 最長遞增子串行

給定正整數序列x1,xn 1 計算其最長遞增子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的遞增子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的遞增子串行。設計有效演算法完成 1 2 3 提出的計算任務。第一問秒掉 第二問比較難想到,每個...