題意:
給定正整數序列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提供輸入...