/* -*- coding: utf-8 -*- * * 3345.cc: No.3345 Reducible Sequence - yukicoder */ #include #include #include #include #include using namespace std; /* constant */ const int MAX_N = 5000; const int MAX_A = 5000; const int INF = 1 << 30; /* typedef */ template struct MaxFlow { using pii = pair; using vpii = vector; using vvpii = vector; int n, m; vvpii nbrs; T inf, max_flow; vpii prvs; vector minfs, caps, flows; MaxFlow(int _n, T _inf): n(_n), m(0), inf(_inf) { nbrs.assign(n, vpii()); minfs.assign(n, 0); prvs.assign(n, {-1, -1}); caps.clear(), flows.clear(); max_flow = 0; } int addedges(int u, int v, T c) { // edge[m]: u -> v, cap=c nbrs[u].push_back({v, m}); caps.push_back(c); flows.push_back(0); // edge[m + 1]: v -> u, cap=0 nbrs[v].push_back({u, m + 1}); caps.push_back(0); flows.push_back(0); m += 2; return m; } T flow(int st, int gl, bool cont = false) { if (! cont) { fill(flows.begin(), flows.end(), 0); max_flow = 0; } for (;;) { //printf("max_flow = %d, limit = %d\n", max_flow, limit); fill(prvs.begin(), prvs.end(), pii(-1, -1)); prvs[st] = {st, -1}; minfs[st] = inf; queue q; q.push(st); while (! q.empty()) { int u = q.front(); q.pop(); if (u == gl) break; for (auto [v, ei]: nbrs[u]) { T vc = caps[ei] - flows[ei]; if (prvs[v].first < 0 && vc > 0) { prvs[v] = {u, ei}; minfs[v] = (minfs[u] < vc) ? minfs[u] : vc; q.push(v); } } } if (prvs[gl].first < 0) break; T min_flow = minfs[gl]; for (int j = gl; j != st;) { auto [i, ei] = prvs[j]; flows[ei] += min_flow; flows[ei ^ 1] -= min_flow; j = i; } max_flow += min_flow; } return max_flow; } }; /* int main() { const int INF = 1 << 30; MaxFlow mf(3, INF); mf.addedges(0, 1, 1); mf.addedges(1, 2, 3); mf.addedges(0, 2, 1); int f = mf.flow(0, 2); printf("f=%d\n", f); return 0; } */ /* global variables */ int as[MAX_N]; /* subroutines */ /* main */ int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", as + i); int st = n * 2, gl = st + 1, gn = gl + 1; MaxFlow mf(gn, INF); for (int i = 0; i < n; i++) mf.addedges(st, i, 0); for (int i = 0; i < n; i++) for (int p = 1; p <= n && p * p <= as[i]; p++) if (as[i] % p == 0) { int q = as[i] / p; mf.addedges(p - 1, n + i, 1); if (q <= n && q != p) mf.addedges(q - 1, n + i, 1); } for (int i = 0; i < n; i++) mf.addedges(n + i, gl, 1); int m = 0; for (bool cont = false; m < n; m++, cont = true) { mf.caps[m * 2] = 1; int f = mf.flow(st, gl, cont); if (f <= m) break; } printf("%d\n", m); return 0; }