網路流24題 P2766

2021-09-22 18:39:07 字數 2215 閱讀 1206

ps最近學習網路流真的是頭大了,學了幾天仍然只會用套dinic做一些簡單的最大流,二分圖匹配等問題,感覺網路流的關鍵是30%的板子水平(必須得深入理解,且易修改)+70%的建模建圖水平,等做到那種萬物皆可網路流就差不多出師了

看了太多神仙建模之後的我做線代高數都想用網路流了,我也太菜了吧ծ‸ծ

«問題描述:

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

(1)計算其最長不下降子串行的長度s。

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

(3)如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的不下降子串行。

«程式設計任務:

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

這道屬於簡單的建圖

先用floyed演算法預處理,得到第一題答案,用f[i]表示如果將第i個數作為序列的最後一位,那最多能有多長,將每乙個點拆成兩個點,入點和出點,容量為1(網路流基操),保證每乙個數隻被選一次

再將f[i]=1的點的入點與源點用inf容量邊連線,最後將f[i]=n的點的出點與匯點也用inf容量邊連線,跑一邊dinic,得到第二個解

第三題只需要將第乙個和最後乙個點的入點與出點之間點的邊容量改為inf就行了

話說洛谷也太好用了吧,要是沒有提供的資料,我估計要死在這一題上了

#include

using namespace std;

const

int maxm=

2000

;const

int max_v =

2000

;const

int inf =

0x3f3f3f3f

;int a[max_v]

,f[max_v]

,b[max_v]

;struct edge

;vector g[maxm]

,g[maxm]

;int level[max_v]

, iter[max_v]

;void

add_edge

(int from,

int to,

int cap));

g[to]

.push_back()

;}intbfs

(int s,

int t)}}

return0;

}int

dfs(

int s,

int t,

int maxf)

}return ret;

}int

dinic

(int s,

int t)

void

initial

(int n)

}void

search

(int n,

int n)

} cout

(int n)

} f[i]

=max1;

ans1=

max(ans1,max1);}

return ans1;

}void

chushi

(int n,

int ans1)

if(f[i]

==ans1)

for(

int j=

1;j<=i-

1;j++)}

}}intmain()

ans1=

lis(n)

;/*for(int i=1;i<=n;i++)

chushi

(n,ans1)

;for

(int i=

0;i<=

2*n+

1;i++

) ans2=

dinic(0

,2*n+1);

cout

int i=

0;i<=

2*n+

1;i++

) g[1]

[0].cap=inf;

g[n][0

].cap=inf;

ans3=

dinic(0

,2*n+1);

cout<}

24題 P2766最長不下降子串行問題

網路流是個好東西,希望我也會。網路流?orz zsy 考慮我們是如何 dp 這個 lis 的。我們是倒著推,設定 dp i 代表以 i 為起點的 lis 是多少。轉移太顯然了 dp i max 1,data i le data j 想一想乙個合法的 lis 方案代表著什麼,代表著它是由這個式子乙個乙...

網路流 之 P2766 最長不下降子串行問題

問題描述 給定正整數序列x1,xn 1 計算其最長不下降子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的不下降子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的不下降子串行。程式設計任務 設計有效演算法完成 1 2 3 提出的計算任務。輸入...

P2766 最長不下降子串行問題 題解(網路流)

最長不下降子串行問題 分成三小問解決。第一小問,求 lis 因為 n 500 直接 o n 2 暴力求解即可。第二三小問,建立模型用網路流求解。對於第二小問 1 首先,因為每個點只能使用一次,考慮拆點,把每乙個點拆成 i,n i 兩個點,從 i 連向 n i 一條長度為 1 的有向邊。2 其次,因為...