Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize("Ofast,unroll-loops")
- #include <algorithm>
- #include <iostream>
- #include <fstream>
- #include <queue>
- #include <cstring>
- #define sz(a) ((int)(a).size())
- #define all(a) (a).begin(), (a).end()
- #define fi first
- #define se second
- #define lsb(x) (x & (-x))
- using namespace std;
- inline bool ckmin(int &a, int b) { if (a <= b) return false; else a = b; return true; }
- inline bool ckmax(int &a, int b) { if (a >= b) return false; else a = b; return true; }
- typedef long long ll;
- typedef pair<int, int> pii;
- const int NMAX = 6005;
- const int INF = 1e9+5;
- struct Edge {
- int dest, cap, cost, other;
- };
- int n;
- int a[NMAX];
- int source, sink;
- vector<Edge> g[NMAX];
- int dist[NMAX], pi[NMAX], pi2[NMAX];
- int vis[NMAX];
- bool inq[NMAX];
- pii nxt[NMAX];
- void add_edge(int x, int y, int cap, int cost) {
- if (!cap) return;
- g[x].push_back({ y, cap, cost, sz(g[y]) });
- g[y].push_back({ x, 0, -cost, sz(g[x]) - 1 });
- }
- void read() {
- cin >> n;
- for (int i = 1; i <= n; i++)
- cin >> a[i];
- }
- void init_pi() {
- for (int i = 1; i <= n; i++)
- pi[i] = INF;
- pi[source] = 0;
- for (int i = 1; i <= ((n - 2) >> 1); i++) {
- for (auto &it : g[i]) {
- if (!it.cap) ckmin(pi[i], pi[it.dest] - it.cost);
- }
- int u = i + ((n - 2) >> 1);
- for (auto &it : g[u]) {
- if (it.dest < u) ckmin(pi[u], pi[it.dest] - it.cost);
- }
- }
- }
- void dijkstra() {
- for (int i = 1; i <= n; i++) {
- dist[i] = INF;
- vis[i] = false;
- pi2[i] = pi[i];
- }
- priority_queue<pii> pq;
- pq.push({0, source});
- dist[source] = pi[source] = 0;
- nxt[source] = {0, 0};
- int i;
- while (!pq.empty()) {
- int u = pq.top().se;
- pq.pop();
- if (vis[u]) continue;
- vis[u] = true;
- i = 0;
- for (auto &it : g[u]) {
- if (it.cap && ckmin(dist[it.dest], dist[u] + it.cost + pi2[u] - pi2[it.dest])) {
- pi[it.dest] = pi[u] + it.cost;
- nxt[it.dest] = { u, i };
- pq.push({-dist[it.dest], it.dest});
- }
- i++;
- }
- }
- }
- int mcf(int flow) {
- int min_cost = 0;
- init_pi();
- while (dijkstra(), dist[sink] != INF && flow) {
- int f = flow, cost = 0;
- for (int u = sink; u != source; u = nxt[u].fi) {
- Edge &e = g[nxt[u].fi][nxt[u].se];
- cost += e.cost;
- ckmin(f, e.cap);
- }
- for (int u = sink; u != source; u = nxt[u].fi) {
- Edge &e = g[nxt[u].fi][nxt[u].se];
- e.cap -= f;
- g[u][e.other].cap += f;
- }
- flow -= f;
- min_cost += f * cost;
- }
- return min_cost;
- }
- int solve() {
- source = 2 * n + 1, sink = 2 * n + 2;
- for (int i = 1; i <= n; i++) {
- add_edge(source, i, 1, n);
- add_edge(i, n + i, 1, -1);
- add_edge(n + i, sink, 1, n);
- for (int j = 1; j < i; j++) {
- if (abs(a[i] - a[j]) <= 1 || a[i] % 7 == a[j] % 7)
- add_edge(n + j, i, 1, 0);
- }
- }
- n += n + 2;
- return -mcf(4) + 8 * ((n - 2) / 2);
- }
- signed main() {
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- #else
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- #endif
- read();
- cout << solve() << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement