網路流24題 P2766 最長不下降子序列問題
阿新 • • 發佈:2020-08-24
思路
咕咕咕
晚上更新
程式碼
/* Name: 最長不下降子序列問題 Author: Loceaner Date: 24/08/20 15:54 Description: Debug: 當最長不下降子序列為1時,需要特判一下,去重之後才能輸出第三個答案,否則會變成inf */ #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int A = 1e5 + 11; const int B = 1e6 + 11; const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f; inline int read() { char c = getchar(); int x = 0, f = 1; for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1; for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); return x * f; } struct node { int to, val, nxt; } e[A]; int dep[A], cur[A], head[A], inq[A]; int n, m, s, t, ans = 0, a[A], f[A], cnt = 1; inline void add(int from, int to, int val) { e[++cnt].to = to; e[cnt].val = val; e[cnt].nxt = head[from]; head[from] = cnt; } inline bool bfs() { queue <int> Q; for (int i = 1; i <= 2 * n + 2; i++) cur[i] = head[i], dep[i] = inf, inq[i] = 0; Q.push(s), dep[s] = 0, inq[s] = 1; while (!Q.empty()) { int x = Q.front(); Q.pop(), inq[x] = 0; for (int i = head[x]; i; i = e[i].nxt) { int to = e[i].to; if (dep[to] > dep[x] + 1 && e[i].val) { dep[to] = dep[x] + 1; if (!inq[to]) Q.push(to), inq[to] = 1; } } } if (dep[t] != inf) return 1; return 0; } int dfs(int x, int flow) { if (x == t) return flow; for (int i = cur[x], tmp = 0; i; i = e[i].nxt) { cur[x] = i; int to = e[i].to; if (dep[to] == dep[x] + 1 && e[i].val) { if (tmp = dfs(to, min(e[i].val, flow))) { e[i].val -= tmp, e[i ^ 1].val += tmp; return tmp; } } } return 0; } int main() { n = read(), s = 2 * n + 1, t = 2 * n + 2; for (int i = 1; i <= n; i++) a[i] = read(); for (int i = 1; i <= n; i++) f[i] = 1; ans = 1; for (int i = 2; i <= n; i++) for (int j = 1; j < i; j++) { if (a[i] >= a[j]) f[i] = max(f[j] + 1, f[i]); ans = max(ans, f[i]); } cout << ans << '\n'; for (int i = 1; i <= n; i++) { add(i, i + n, 1), add(i + n, i, 0); if (f[i] == 1) add(s, i, 1), add(i, s, 0); if (f[i] == ans) add(i + n, t, 1), add(t, i + n, 0); for (int j = 1; j < i; j++) if (a[j] <= a[i] && f[i] == f[j] + 1) add(j + n, i, 1), add(i, j + n, 0); } int now = 0, ans1 = 0; if (ans == 1) { cout << n << '\n'; sort(a + 1, a + 1 + n); int len = unique(a + 1, a + 1 + n) - a - 1; cout << len << '\n'; return 0; } while (bfs()) while (now = dfs(s, inf)) ans1 += now; cout << ans1 << '\n'; add(s, 1, inf), add(1, s, 0); add(1, 1 + n, inf), add(1 + n, 1, 0); if (f[n] == ans) add(n, n * 2, inf), add(n * 2, n, 0), add(n * 2, t, inf), add(t, n * 2, 0);; while (bfs()) while (now = dfs(s, inf)) ans1 += now; cout << ans1 << '\n'; return 0; }