Problem p01239 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
#define INF (1e9)
#define MAX_N 14
using namespace std;
typedef complex<double> P;
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
int n;
double x, y;
double dp[(1 << MAX_N)][MAX_N * 2];
vector<P> v;

int main() {
  int T = 1;
  while (1) {
    cin >> n;
    if (!n)
      break;
    double ans = 0;
    for (int i = 0; i < n; i++) {
      cin >> x >> y;
      v.push_back(P(x, y));
      cin >> x >> y;
      v.push_back(P(x, y));
      ans += abs(v[v.size() - 1] - v[v.size() - 2]);
    }
    Fill(dp, INF);
    for (int i = 0; i < n * 2; i++)
      dp[(1 << (i / 2))][i] = 0;
    for (int i = 0; i < (1 << n); i++) {
      for (int j = 0; j < n * 2; j++) {
        if (dp[i][j] == INF)
          continue;
        int p1 = j;
        for (int l = 0; l < n; l++) {
          if (i & (1 << l))
            continue;
          int p3 = l * 2, p4 = l * 2 + 1;
          int next = p4;
          dp[i | (1 << l)][next] =
              min(dp[i | (1 << l)][next], dp[i][j] + abs(v[p1] - v[p3]));
          next = p3;
          dp[i | (1 << l)][next] =
              min(dp[i | (1 << l)][next], dp[i][j] + abs(v[p1] - v[p4]));
        }
      }
    }
    double minl = INF;
    for (int i = 0; i < n * 2; i++)
      minl = min(minl, dp[(1 << n) - 1][i]);
    ans += minl;
    cout << "Case " << T << ": ";
    printf("%.5f\\n", ans);
    T++;
    v.clear();
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define INF (1e9)
#define MAX_N 14
using namespace std;
typedef complex<double> P;
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
int n;
double x, y;
double dp[(1 << MAX_N)][MAX_N * 2][MAX_N * 2];
vector<P> v;

int main() {
  int T = 1;
  while (1) {
    cin >> n;
    if (!n)
      break;
    double ans = 0;
    for (int i = 0; i < n; i++) {
      cin >> x >> y;
      v.push_back(P(x, y));
      cin >> x >> y;
      v.push_back(P(x, y));
      ans += abs(v[v.size() - 1] - v[v.size() - 2]);
    }
    Fill(dp, INF);
    for (int i = 0; i < n * 2; i++)
      for (int j = i + 1; j < n * 2; j++) {
        if (i / 2 == j / 2)
          continue;
        int A = i, B = j;
        if (A % 2)
          A--;
        else
          A++;
        if (B % 2)
          B--;
        else
          B++;
        dp[(1 << (i / 2)) | (1 << (j / 2))][A][B] = abs(v[i] - v[j]);
      }
    for (int i = 0; i < (1 << n); i++) {
      for (int j = 0; j < n * 2; j++) {
        for (int k = j + 1; k < n * 2; k++) {
          if (j / 2 == k / 2)
            continue;
          if (dp[i][j][k] == INF)
            continue;
          int p1 = j, p2 = k;
          for (int l = 0; l < n; l++) {
            if (i & (1 << l))
              continue;
            int p3 = l * 2, p4 = l * 2 + 1;
            int L = min(p2, p4), R = max(p2, p4);
            dp[i | (1 << l)][L][R] =
                min(dp[i | (1 << l)][L][R], dp[i][j][k] + abs(v[p1] - v[p3]));
            L = min(p2, p3), R = max(p2, p3);
            dp[i | (1 << l)][L][R] =
                min(dp[i | (1 << l)][L][R], dp[i][j][k] + abs(v[p1] - v[p4]));
            L = min(p1, p4), R = max(p1, p4);
            dp[i | (1 << l)][L][R] =
                min(dp[i | (1 << l)][L][R], dp[i][j][k] + abs(v[p2] - v[p3]));
            L = min(p1, p3), R = max(p1, p3);
            dp[i | (1 << l)][L][R] =
                min(dp[i | (1 << l)][L][R], dp[i][j][k] + abs(v[p2] - v[p4]));
          }
        }
      }
    }
    double minl = INF;
    for (int i = 0; i < n * 2; i++)
      for (int j = i + 1; j < n * 2; j++)
        minl = min(minl, dp[(1 << n) - 1][i][j]);
    ans += minl;
    cout << "Case " << T << ": ";
    printf("%.5f\\n", ans);
    T++;
    v.clear();
  }
  return 0;
}