Problem p02798 (C++)

Buggy submission (status: Runtime Error):
#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <cmath>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

#define endl "\n"
#define age first
#define pos second
#define Z third
#define mp make_pair
#define mt make_triple

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const ld PI = 3.141592653589793;
const ld E = 2.71828182845904523;
const ll LLINF = 4000000009000000099;
const ll INF = 1009000099;
const ll MOD7 = 1000000007;
const ll MOD9 = 1000000009;

template <class A, class B, class C> struct triple {
  A first;
  B second;
  C third;
  triple(A, B, C);
  triple();
};
template <class A, class B, class C> triple<A, B, C>::triple(A a, B b, C c) {
  first = a;
  second = b;
  third = c;
}
template <class A, class B, class C> triple<A, B, C>::triple() {}
template <class A, class B, class C>
triple<A, B, C> make_triple(A a, B b, C c) {
  triple<A, B, C> t(a, b, c);
  return t;
}
template <class A, class B, class C>
bool operator<(triple<A, B, C> a, triple<A, B, C> b) {
  if (a.first != b.first)
    return a.first < b.first;
  if (a.second != b.second)
    return a.second < b.second;
  if (a.third != b.third)
    return a.third < b.third;
}
template <class T> T inline sqr(T a) { return a * a; }

inline ll bpow(ll a, ll d, ll mod) {
  ll res = 1, p = a;
  while (d != 0) {
    if (d & 1) {
      res *= p;
      res %= mod;
    }
    p = (p * p) % mod;
    d >>= 1;
  }

  return res;
}
ll bpow(ll a, ll d) {
  if (d == 0)
    return 1;
  ll t = bpow(a, d / 2);
  t = (t * t);
  if (d & 1)
    t = (t * a);
  return t;
}
ll gcd(ll a, ll b) {
  while (a && b)
    if (a > b)
      a %= b;
    else
      b %= a;
  return a + b;
}
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
ll C(ll n, ll k) {
  ll res = 1;
  for (int i = 1; i <= k; ++i)
    res = res * (n - k + i) / i;
  return res;
}
inline ll C(ll n, ll k, ll mod) {
  ll u = 1, d = 1;
  for (int i = 2; i <= n; ++i)
    u = (u * i) % mod;
  int x = max(k, n - k), z = min(k, n - k);
  for (int i = 2; i <= x; ++i) {
    d = (d * i) % mod;
    if (i <= z)
      d = (d * i) % mod;
  }
  d = bpow(d, mod - 2, mod);
  ll res = (u * d) % mod;
  return res;
}

using namespace std;

void solve1() {
  int n;
  cin >> n;
  vector<pair<int, int>> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i].first;
    v[i].second = i;
  }
  sort(v.begin(), v.end());

  vector<set<int>> cycles;
  set<int> used;
  for (int i = 0; i < n; ++i) {
    set<int> s;
    int idx = i;
    while (used.find(v[idx].first) == used.end()) {
      used.insert(v[idx].first);
      s.insert(v[idx].first);
      idx = v[idx].second;
    }

    if (s.size() > 1)
      cycles.push_back(s);
  }
  int res = 0, glMin = v.front().first;
  for (auto cycle : cycles) {
    int sum = 0, locMin = *cycle.begin();
    for (auto it = cycle.begin(); it != cycle.end(); ++it)
      sum += *it;
    res += min(sum + locMin * (cycle.size() - 2),
               sum + locMin + glMin * (cycle.size() + 1));
  }

  cout << res << endl;
}

bool cmp(pair<ll, ll> a, pair<ll, ll> b) {
  if (a.second != b.second)
    return a.second < b.second;

  return a.first > b.first;
}

bool doesIntersect(pair<ll, ll> a, pair<ll, ll> b) {
  ll r = min(a.second, b.second), l = max(a.first, b.first);

  return r > l;
}

ll value(const vector<vector<ll>> &v, int start, int finish) {
  int shift = abs(start - finish);
  return v[start][shift & 1];
}

int popcnt(int x) {
  int cnt = 0;
  while (x) {
    cnt++;
    x &= x - 1;
  }
  return cnt;
}

void solve() {
  ll n;
  cin >> n;
  const ll MAX_N = 8;
  vector<vector<ll>> v(n);
  int sz = 2;
  for (int j = 0; j < sz; ++j)
    for (int i = 0; i < n; ++i) {
      int x;
      cin >> x;
      v[i].push_back(x);
    }

  int dp[1 << MAX_N][MAX_N];

  for (int i = 0; i < (1 << MAX_N); ++i)
    for (int j = 0; j < MAX_N; ++j)
      dp[i][j] = -1;

  for (int i = 0; i < n; ++i)
    dp[(1 << i)][i] = i;

  for (int i = 1; i < (1 << n); ++i) {
    int cnt = popcnt(i);
    int side_effect = cnt - 1;
    for (int j = 0; j < n; ++j)
      if ((i & (1 << j)) && dp[i][j] == -1) {
        dp[i][j] = INF;
        int umask = i ^ (1 << j);
        int shift = abs(cnt - 1 - (j + side_effect));
        for (int k = 0; k < n; ++k)
          if ((umask & (1 << k)) &&
              value(v, j, cnt - 1) >= value(v, k, cnt - 2))
            dp[i][j] = min(dp[umask][k] + shift, dp[i][j]);
        --side_effect;
      }
  }

  int ans = INF;

  for (int i = 0; i < n; ++i)
    ans = min(ans, dp[(1 << n) - 1][i]);

  if (ans < INF)
    cout << ans;
  else
    cout << -1;
}

int main() {
  cin.tie(0);
  cout.tie(0);
  ios::sync_with_stdio(0);
#ifdef _DEBUG
  freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
#endif
  solve();
  return 0;
}


Fixed submission:
#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <cmath>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

#define endl "\n"
#define age first
#define pos second
#define Z third
#define mp make_pair
#define mt make_triple

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const ld PI = 3.141592653589793;
const ld E = 2.71828182845904523;
const ll LLINF = 4000000009000000099;
const ll INF = 1009000099;
const ll MOD7 = 1000000007;
const ll MOD9 = 1000000009;

template <class A, class B, class C> struct triple {
  A first;
  B second;
  C third;
  triple(A, B, C);
  triple();
};
template <class A, class B, class C> triple<A, B, C>::triple(A a, B b, C c) {
  first = a;
  second = b;
  third = c;
}
template <class A, class B, class C> triple<A, B, C>::triple() {}
template <class A, class B, class C>
triple<A, B, C> make_triple(A a, B b, C c) {
  triple<A, B, C> t(a, b, c);
  return t;
}
template <class A, class B, class C>
bool operator<(triple<A, B, C> a, triple<A, B, C> b) {
  if (a.first != b.first)
    return a.first < b.first;
  if (a.second != b.second)
    return a.second < b.second;
  if (a.third != b.third)
    return a.third < b.third;
}
template <class T> T inline sqr(T a) { return a * a; }

inline ll bpow(ll a, ll d, ll mod) {
  ll res = 1, p = a;
  while (d != 0) {
    if (d & 1) {
      res *= p;
      res %= mod;
    }
    p = (p * p) % mod;
    d >>= 1;
  }

  return res;
}
ll bpow(ll a, ll d) {
  if (d == 0)
    return 1;
  ll t = bpow(a, d / 2);
  t = (t * t);
  if (d & 1)
    t = (t * a);
  return t;
}
ll gcd(ll a, ll b) {
  while (a && b)
    if (a > b)
      a %= b;
    else
      b %= a;
  return a + b;
}
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
ll C(ll n, ll k) {
  ll res = 1;
  for (int i = 1; i <= k; ++i)
    res = res * (n - k + i) / i;
  return res;
}
inline ll C(ll n, ll k, ll mod) {
  ll u = 1, d = 1;
  for (int i = 2; i <= n; ++i)
    u = (u * i) % mod;
  int x = max(k, n - k), z = min(k, n - k);
  for (int i = 2; i <= x; ++i) {
    d = (d * i) % mod;
    if (i <= z)
      d = (d * i) % mod;
  }
  d = bpow(d, mod - 2, mod);
  ll res = (u * d) % mod;
  return res;
}

using namespace std;

void solve1() {
  int n;
  cin >> n;
  vector<pair<int, int>> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i].first;
    v[i].second = i;
  }
  sort(v.begin(), v.end());

  vector<set<int>> cycles;
  set<int> used;
  for (int i = 0; i < n; ++i) {
    set<int> s;
    int idx = i;
    while (used.find(v[idx].first) == used.end()) {
      used.insert(v[idx].first);
      s.insert(v[idx].first);
      idx = v[idx].second;
    }

    if (s.size() > 1)
      cycles.push_back(s);
  }
  int res = 0, glMin = v.front().first;
  for (auto cycle : cycles) {
    int sum = 0, locMin = *cycle.begin();
    for (auto it = cycle.begin(); it != cycle.end(); ++it)
      sum += *it;
    res += min(sum + locMin * (cycle.size() - 2),
               sum + locMin + glMin * (cycle.size() + 1));
  }

  cout << res << endl;
}

bool cmp(pair<ll, ll> a, pair<ll, ll> b) {
  if (a.second != b.second)
    return a.second < b.second;

  return a.first > b.first;
}

bool doesIntersect(pair<ll, ll> a, pair<ll, ll> b) {
  ll r = min(a.second, b.second), l = max(a.first, b.first);

  return r > l;
}

ll value(const vector<vector<ll>> &v, int start, int finish) {
  int shift = abs(start - finish);
  return v[start][shift & 1];
}

int popcnt(int x) {
  int cnt = 0;
  while (x) {
    cnt++;
    x &= x - 1;
  }
  return cnt;
}

void solve() {
  ll n;
  cin >> n;
  const ll MAX_N = 18;
  vector<vector<ll>> v(n);
  int sz = 2;
  for (int j = 0; j < sz; ++j)
    for (int i = 0; i < n; ++i) {
      int x;
      cin >> x;
      v[i].push_back(x);
    }

  int dp[1 << MAX_N][MAX_N];

  for (int i = 0; i < (1 << MAX_N); ++i)
    for (int j = 0; j < MAX_N; ++j)
      dp[i][j] = -1;

  for (int i = 0; i < n; ++i)
    dp[(1 << i)][i] = i;

  for (int i = 1; i < (1 << n); ++i) {
    int cnt = popcnt(i);
    int side_effect = cnt - 1;
    for (int j = 0; j < n; ++j)
      if ((i & (1 << j)) && dp[i][j] == -1) {
        dp[i][j] = INF;
        int umask = i ^ (1 << j);
        int shift = abs(cnt - 1 - (j + side_effect));
        for (int k = 0; k < n; ++k)
          if ((umask & (1 << k)) &&
              value(v, j, cnt - 1) >= value(v, k, cnt - 2))
            dp[i][j] = min(dp[umask][k] + shift, dp[i][j]);
        --side_effect;
      }
  }

  int ans = INF;

  for (int i = 0; i < n; ++i)
    ans = min(ans, dp[(1 << n) - 1][i]);

  if (ans < INF)
    cout << ans;
  else
    cout << -1;
}

int main() {
  cin.tie(0);
  cout.tie(0);
  ios::sync_with_stdio(0);
#ifdef _DEBUG
  freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
#endif
  solve();
  return 0;
}