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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
int n, x[19], y[19], h[129][19][19], dp[65555][549];
bool vis[65555][549];
map<pair<int, int>, vector<pair<int, int>>> d;
vector<vector<pair<int, int>>> v;
int gcd(int pa, int pb) {
  if (pb == 0)
    return pa;
  return gcd(pb, pa % pb);
}
int solve(int bit, int p1, int p2, int cur) {
  if (p1 == v.size())
    return 0;
  if (p2 == v[p1].size()) {
    int res = solve(bit, p1 + 1, 0, 0);
    return res + cur * (cur - 1) / 2;
  }
  if (vis[bit][h[p1][p2][cur]])
    return dp[bit][h[p1][p2][cur]];
  int pa = v[p1][p2].first, pb = v[p1][p2].second;
  int ret = solve(bit, p1, p2 + 1, cur);
  if (!(bit & (1 << pa)) && !(bit & (1 << pb))) {
    int res = solve(bit | (1 << pa) | (1 << pb), p1, p2 + 1, cur + 1);
    ret = max(ret, res);
  }
  vis[bit][h[p1][p2][cur]] = true;
  dp[bit][h[p1][p2][cur]] = ret;
  return ret;
}
int main() {
  cin >> n;
  for (int i = 0; i < n; i++)
    cin >> x[i] >> y[i];
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      int vx = x[j] - x[i], vy = y[j] - y[i];
      if (vy < 0)
        vy = -vy, vx = -vx;
      if (vy == 0 && vx < 0)
        vx = -vx;
      int g = gcd(abs(vx), vy);
      d[make_pair(abs(vx) / g * (vx > 0 ? 1 : -1), vy / g)].push_back(
          make_pair(i, j));
    }
  }
  for (pair<pair<int, int>, vector<pair<int, int>>> i : d) {
    v.push_back(i.second);
  }
  int curs = 0;
  for (int i = 0; i < v.size(); i++) {
    for (int j = 0; j < v[i].size(); j++) {
      for (int k = 0; k <= j; k++) {
        h[i][j][k] = curs++;
      }
    }
  }
  int ret = solve(0, 0, 0, 0);
  cout << ret << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
int n, x[19], y[19], h[129][19], dp[65555][129][10];
bool vis[65555][129][10];
map<pair<int, int>, vector<pair<int, int>>> d;
vector<vector<pair<int, int>>> v;
int gcd(int pa, int pb) {
  if (pb == 0)
    return pa;
  return gcd(pb, pa % pb);
}
int solve(int bit, int p1, int p2, int cur) {
  if (p1 == v.size())
    return 0;
  if (p2 == v[p1].size()) {
    int res = solve(bit, p1 + 1, 0, 0);
    return res + cur * (cur - 1) / 2;
  }
  if (vis[bit][h[p1][p2]][cur])
    return dp[bit][h[p1][p2]][cur];
  int pa = v[p1][p2].first, pb = v[p1][p2].second;
  int ret = solve(bit, p1, p2 + 1, cur);
  if (!(bit & (1 << pa)) && !(bit & (1 << pb))) {
    int res = solve(bit | (1 << pa) | (1 << pb), p1, p2 + 1, cur + 1);
    ret = max(ret, res);
  }
  vis[bit][h[p1][p2]][cur] = true;
  dp[bit][h[p1][p2]][cur] = ret;
  return ret;
}
int main() {
  cin >> n;
  for (int i = 0; i < n; i++)
    cin >> x[i] >> y[i];
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      int vx = x[j] - x[i], vy = y[j] - y[i];
      if (vy < 0)
        vy = -vy, vx = -vx;
      int g = gcd(abs(vx), vy);
      d[make_pair(abs(vx) / g * (vx > 0 ? 1 : -1), vy / g)].push_back(
          make_pair(i, j));
    }
  }
  for (pair<pair<int, int>, vector<pair<int, int>>> i : d) {
    v.push_back(i.second);
  }
  int curs = 0;
  for (int i = 0; i < v.size(); i++) {
    for (int j = 0; j < v[i].size(); j++) {
      h[i][j] = curs++;
    }
  }
  int ret = solve(0, 0, 0, 0);
  cout << ret << endl;
  return 0;
}