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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const double EPS = 1.0e-10;

class Point {
public:
  double y, x;
  Point() { y = x = 0.0; }
  Point(double y0, double x0) {
    y = y0;
    x = x0;
  }
  Point operator+(const Point &p) const { return Point(y + p.y, x + p.x); }
  Point operator-(const Point &p) const { return Point(y - p.y, x - p.x); }
  Point operator*(double a) const { return Point(y * a, x * a); }
  Point operator/(double a) const { return Point(y / a, x / a); }
  double length() const { return sqrt(y * y + x * x); }
  double dist(const Point &p) const {
    return sqrt(pow(y - p.y, 2) + pow(x - p.x, 2));
  }
  double dot(const Point &p) const {
    return y * p.y + x * p.x; // |a|*|b|*cos慮
  }
  double cross(const Point &p) const {
    return x * p.y - y * p.x; // |a|*|b|*sin慮
  }
};

int n;
vector<double> distDevil;
vector<vector<double>> dist;

bool solve(int curr, bitset<21> visited, double t) {
  if (visited.to_ulong() == (1 << n) - 1)
    return true;

  for (int i = 0; i < n; ++i) {
    if (!visited[i] && t + dist[curr][i] > distDevil[i] - EPS)
      return false;
  }

  for (int i = 0; i < n; ++i) {
    if (!visited[i]) {
      visited[i] = true;
      if (solve(i, visited, t + dist[curr][i]))
        return true;
      visited[i] = false;
    }
  }

  return false;
}

int main() {
  for (;;) {
    Point h, d;
    cin >> n >> h.x >> h.y >> d.x >> d.y;
    if (n == 0)
      return 0;

    ++n;
    vector<Point> p(n);
    p[0] = h;
    for (int i = 1; i < n; ++i)
      cin >> p[i].x >> p[i].y;

    distDevil.resize(n);
    for (int i = 0; i < n; ++i)
      distDevil[i] = d.dist(p[i]);

    dist.assign(n, vector<double>(n));
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        dist[i][j] = p[i].dist(p[j]);
      }
    }

    if (solve(0, 1, 0.0))
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const double INF = DBL_MAX / 1000;
const double EPS = 1.0e-10;

class Point {
public:
  double y, x;
  Point() { y = x = 0.0; }
  Point(double y0, double x0) {
    y = y0;
    x = x0;
  }
  Point operator+(const Point &p) const { return Point(y + p.y, x + p.x); }
  Point operator-(const Point &p) const { return Point(y - p.y, x - p.x); }
  Point operator*(double a) const { return Point(y * a, x * a); }
  Point operator/(double a) const { return Point(y / a, x / a); }
  double length() const { return sqrt(y * y + x * x); }
  double dist(const Point &p) const {
    return sqrt(pow(y - p.y, 2) + pow(x - p.x, 2));
  }
  double dot(const Point &p) const {
    return y * p.y + x * p.x; // |a|*|b|*cos慮
  }
  double cross(const Point &p) const {
    return x * p.y - y * p.x; // |a|*|b|*sin慮
  }
};

int main() {
  for (;;) {
    int n;
    Point h, d;
    cin >> n >> h.x >> h.y >> d.x >> d.y;
    if (n == 0)
      return 0;

    ++n;
    vector<Point> p(n);
    p[0] = h;
    for (int i = 1; i < n; ++i)
      cin >> p[i].x >> p[i].y;

    vector<double> distDevil(n);
    for (int i = 0; i < n; ++i)
      distDevil[i] = d.dist(p[i]);

    vector<vector<double>> dist(n, vector<double>(n));
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        dist[i][j] = p[i].dist(p[j]);
      }
    }

    vector<vector<double>> dp(1 << n, vector<double>(n, INF));
    dp[1][0] = 0.0;
    for (int i = 0; i < (1 << n); ++i) {
      bitset<21> bs(i);
      for (int j = 0; j < n; ++j) {
        if (!bs[j])
          continue;
        for (int k = 0; k < n; ++k) {
          if (bs[k])
            continue;

          bs[k] = true;
          double t = dp[i][j] + dist[j][k];
          if (t < distDevil[k] - EPS)
            dp[bs.to_ulong()][k] = t;
          bs[k] = false;
        }
      }
    }

    double ret = *min_element(dp[(1 << n) - 1].begin(), dp[(1 << n) - 1].end());
    if (ret < INF / 10)
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
}