1741 最長遞增子串行問題 dp 網路流

2021-08-21 15:26:54 字數 1510 閱讀 7411

題意:

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

思路:dp【i】表示以i為開頭的lis長度,用ans代表整個序列的lis長度,對於第二問首先拆點,講乙個點拆成入點和出點,然後在入點和出點間連一條容量為1的有向邊,之後在s與dp【i】為ans的入點之間連容量為1的有向邊,然後在a【i】#include #include #include #include #include using namespace std;

const int maxn = 1000;

const int inf = 0x3f3f3f3f;

struct edge ;

struct dinic

void addedge(int from, int to, int cap) );

edges.push_back(edge);

int x = edges.size();

g[from].push_back(x-2);

g[to].push_back(x-1);

}bool bfs() }}

return vis[t];

}int dfs(int x, int a)

}return flow;

}int maxflow(int s, int t)

return flow;

}}ac, ac2;

int n, a[maxn], dp[maxn];

int main()

ans = max(ans, dp[i]);

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

if (ans == 1)

ac.init();

for (int i = 1; i <= n; i++) ac.addedge(i, i+n, 1);

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

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

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

printf("%d\n", ac.maxflow(s, t));

ac2.init();

ac2.addedge(1, 1+n, inf);

for (int i = 2; i <= n-1; i++) ac2.addedge(i, i+n, 1);

ac2.addedge(n, n+n, inf);

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

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

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

}printf("%d\n", ac2.maxflow(s, t));

return 0;

}

dp 最長遞增子串行 (LIS)

首先引出乙個例子 問題 給你乙個長度為 6 的陣列 陣列元素為 則其最長單調遞增子串行為 並且長度為 5 分析 題目所要找的遞增子串行 想想有什麼特點呢 是不是會發現 所有的遞增序列 前乙個數一定小於後乙個數 並且如果給所有從小到大的數標號 會得到一串遞增的數 既然是借助動態規劃分析問題 那麼當前的...

最長遞增子串行問題

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

最長遞增子串行問題

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