Problem p02798 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T> ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v)
    out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007              // 1e9+7(prime number)
#define INF 1000000000              // 1e9
#define LLINF 2000000000000000000LL // 2e18
#define SIZE 20

int dp[1 << 18][50];

int main() {
  int N, A[SIZE], B[SIZE];

  cin >> N;

  for (int i = 0; i < N; i++)
    cin >> A[i];
  for (int i = 0; i < N; i++)
    cin >> B[i];

  for (int i = 0; i < N; i++) {
    A[i]--;
    B[i]--;
  }

  for (int i = 0; i < (1 << N); i++)
    for (int j = 0; j < 50; j++)
      dp[i][j] = INF;

  dp[0][0] = 0;

  for (int i = 0; i < (1 << N); i++) {
    for (int k = 0; k < 50; k++) {
      cerr << i << " " << k << " : " << dp[i][k] << endl;

      if (dp[i][k] == INF)
        continue;

      for (int j = 0; j < N; j++) {
        if (i & (1 << j))
          continue;

        int maskR = ((1 << N) - 1) - ((1 << (j + 1)) - 1);
        int maskL = ((1 << j) - 1);

        int cR = __builtin_popcount(i & maskR);
        int cL = j - __builtin_popcount(i & maskL);

        if ((cL + cR) % 2) {
          if (k <= B[j]) {
            dp[i | (1 << j)][B[j]] = min(dp[i | (1 << j)][B[j]], dp[i][k] + cL);
          }
        } else {
          if (k <= A[j]) {
            dp[i | (1 << j)][A[j]] = min(dp[i | (1 << j)][A[j]], dp[i][k] + cL);
          }
        }
      }
    }
  }

  int ans = INF;

  for (int i = 0; i < 50; i++) {
    ans = min(ans, dp[(1 << N) - 1][i]);
  }

  if (ans == INF)
    ans = -1;

  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T> ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v)
    out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007              // 1e9+7(prime number)
#define INF 1000000000              // 1e9
#define LLINF 2000000000000000000LL // 2e18
#define SIZE 20

int dp[1 << 18][50];

int main() {
  int N, A[SIZE], B[SIZE];

  cin >> N;

  for (int i = 0; i < N; i++)
    cin >> A[i];
  for (int i = 0; i < N; i++)
    cin >> B[i];

  for (int i = 0; i < N; i++) {
    A[i]--;
    B[i]--;
  }

  for (int i = 0; i < (1 << N); i++)
    for (int j = 0; j < 50; j++)
      dp[i][j] = INF;

  dp[0][0] = 0;

  for (int i = 0; i < (1 << N); i++) {
    for (int k = 0; k < 50; k++) {
      if (dp[i][k] == INF)
        continue;

      for (int j = 0; j < N; j++) {
        if (i & (1 << j))
          continue;

        int maskR = ((1 << N) - 1) - ((1 << (j + 1)) - 1);
        int maskL = ((1 << j) - 1);

        int cR = __builtin_popcount(i & maskR);
        int cL = j - __builtin_popcount(i & maskL);

        if ((cL + cR) % 2) {
          if (k <= B[j]) {
            dp[i | (1 << j)][B[j]] = min(dp[i | (1 << j)][B[j]], dp[i][k] + cL);
          }
        } else {
          if (k <= A[j]) {
            dp[i | (1 << j)][A[j]] = min(dp[i | (1 << j)][A[j]], dp[i][k] + cL);
          }
        }
      }
    }
  }

  int ans = INF;

  for (int i = 0; i < 50; i++) {
    ans = min(ans, dp[(1 << N) - 1][i]);
  }

  if (ans == INF)
    ans = -1;

  cout << ans << endl;

  return 0;
}