codevs1906 最長遞增子串行問題 最大流

2021-07-10 09:38:42 字數 1898 閱讀 4438

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

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

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

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

度為s的遞增子串行。

第1 行有1個正整數n,表示給定序列的長度。接

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

第1 行是最長遞增子串行的長度s。第2行是可取出的長度為s 的遞增子串行個數。第3行是允許在取出的序列中多次使用x1和xn時可取出的長度為s 的遞增子串行個數。

4

3 6 2 5

2

23

第一問dp,然後我就不會做了…

聯絡到最大流每個流代表乙個方案,可以這樣建圖:

數列每個點拆點,然後連流量為1的邊,表示只能選一遍。

對於第一問得到的dp陣列,表示以第

i 位結尾的最長遞增子串的長度。若dp

[i]=

1,則s向i連邊,容量為1;若dp

[i]=

maxl

en(也就是第一問答案),則i′

向e連邊,容量為1。

然後若i

>j且

a[i]

>=a[

j]且d

p[i]

==dp[

j]+1

,則i′ 向

j 連邊,容量為1。

然後跑最大流,每個流表示乙個方案。

對於第三問,把與第1個和第n個點相關的邊改為inf即可(也就是

<1,

1′>n′

>1>,e

>

),跑一遍最大流即可。

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int inf = 1000000010;

const

int sz = 1000010;

int head[sz],nxt[sz],tot = 1,n;

struct edgel[sz];

void build(int f,int t,int d)

void insert(int f,int t,int d)

int deep[sz];

queue

q;bool bfs(int s,int e)}}

return

false;

}int dfs(int u,int flow,int e)

else deep[v] = 0;}}

return flow - rest;

}int dinic(int s,int e)

int dp[sz],num[sz],len = 0;

void init()

int ask(int p)

if(dp[i] == len)

}for(int i = 1;i <= n;i ++)

for(int j = i + 1;j <= n;j ++)

if(num[i] <= num[j] && dp[i] + 1 == dp[j])

insert(i + n,j,1);

return dinic(s,e);

}int main()

printf("%d\n",len);

printf("%d\n",ask(1));

printf("%d\n",ask(inf));

return

0;}

codevs1906 最長遞增子串行問題

題目描述 description 給定正整數序列x1,xn 1 計算其最長遞增子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的遞增子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長 度為s的遞增子串行。輸入描述 input description ...

最長遞增子串行

這是微軟實習生筆試遇到的,題意 求乙個陣列中最長遞增子串行的長度。要求選擇該題最好演算法的時間複雜度和空間複雜度。答案 時間複雜度o nlgn 空間複雜度o n 這題明顯用動態規劃來解。假設在目標陣列array 的前i個元素中,以array i 元素為最大元素的遞增子串行的長度是lis i 那麼 遞...

最長遞增子串行

最長遞增子串行又叫做最長上公升子串行 子串行,正如lcs一樣,元素不一定要求連續。本節討論實現三種常見方法,主要是練手。題 求乙個一維陣列arr i 中的最長遞增子串行的長度,如在序列1,1,2,3,4,5,6,7中,最長遞增子串行長度為4,可以是1,2,4,6,也可以是 1,2,4,6。方法一 d...