最長遞增子串行問題

2021-07-28 18:42:06 字數 2206 閱讀 1322

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

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

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

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

設計有效演算法完成(1)(2)(3)提出的計算任務。
由檔案input.txt提供輸入資料。檔案第1行有1個正整數n,表示給定序列的長度。接下來的1行有n個正整數x1,···,xn。
程式執行結束時,將任務(1)(2)(3)的解答輸出到檔案 output.txt中。第1 行是最長遞增子串行的長度s。第2行是可取出的長度為s的遞增

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

input.txt 

43 6 2 5

output.txt22

3

問題(1)可以用dp進行求解。

對於問題(2)和(3),我們可以用網路流解決。對於每乙個數字,我們都看作節點並進行拆點,以達到限流的目的。對於每乙個dp值為1,也就是以這個數為結尾的最長上公升子串行長度為1,的節點,我們可以從源點引一條邊連向這個點。同理,對於每乙個dp值最大的節點,我們從它引一條邊連向匯點。這種建圖方式也蘊含了分層圖的思想。(即從源點開始,bfs到的點分別是dp為1、2、3的點)

因為我們要構建分層圖,所以對於每乙個f[i]==f[j]+1,s[i]>=s[j] (j < i)的情況,我們從j拆點後的點引一條邊連向i點(本人一開始連邊的時候是從i的拆點指向j,但是去掉f[i]==f[j]+1的條件可以得到82分,我能說是資料太水了麼)

code:

#include

#include

const

int inf=1e9;

struct

queue

inline

void push(int n)

inline

int front()

inline

void pop()

inline

bool empty()

}q;struct edge

a[200001];

int head[1001];

int deep[1001];

int s[1001];

int f[1001];

int n,num=1,ans,s,t;

inline

int max(int a,int b)

inline

int min(int a,int b)

inline

bool bfs()

return deep[t]int dfs(int now,int limit)

deep[now]=-1;

return flow;

}inline

int dinic()

int main()

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

//1~n:原點 n+1~2*n:拆點 2*n+1:源點 2*n+2:匯點

s=n<<1|1;t=s+1;

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

add(i,n+i,1);

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

for(int i=2;i<=n;i++)

for(int j=1;jif(s[j]<=s[i]&&f[j]==f[i]-1) add(n+j,i,1);

ans=dinic();printf("%d\n",ans);

for(int i=head[s];i;i=a[i].next)

if(a[i].to==1)

for(int i=head[1];i;i=a[i].next)

if(a[i].to==n+1)

for(int i=head[n<<1];i;i=a[i].next)

if(a[i].to==t)

for(int i=head[n];i;i=a[i].next)

if(a[i].to==n<<1)

ans+=dinic();printf("%d",ans);

return

0;}

最長遞增子串行問題

給定乙個長度為n的陣列,找出乙個最長的單調自增子序列 不一定連續,但是順序不能亂 例如 給定乙個長度為6的陣列a,則其最長的單調遞增子串行為,長度為4.include define maxn 100 假設最多有100個元素 using namespace std int l maxn l i 表示元...

最長遞增子串行問題

某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入資料為飛彈依次飛來的高度,所...

最長遞增子串行問題

目錄 最長遞增子串行問題 合唱隊問題應用 最長公共子串 lcs 問題 給定乙個長度為n的陣列,找出乙個最長的單調自增子序列 不一定連續,但是順序不能亂 例如 給定乙個長度為6的陣列a,則其最長的單調遞增子串行為,長度為4.dp法 設長度為n的陣列為 for int i 1 i 0 j int max...