Problem p01350 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
const double PI = acos(-1);
const double INF = 1e15;
double dp[10010][20][20];

int n;
double r, theta;
double x[20], y[20];

double dist(double x1, double y1, double x2, double y2) {
  x1 -= x2, y1 -= y2;
  return sqrt(x1 * x1 + y1 * y1);
}

double dot(double x1, double y1, double x2, double y2) {
  return x1 * x2 + y1 * y2;
}

bool check(int v, int u, int pre) {
  double ax = x[v] - x[pre];
  double ay = y[v] - y[pre];
  double bx = x[u] - x[v];
  double by = y[u] - y[v];
  double da = dist(x[v], y[v], x[pre], y[pre]);
  double db = dist(x[u], y[u], x[v], y[v]);
  double t = abs(acos(dot(ax, ay, bx, by) / da / db));
  // cerr << "\\t\\t" << v << " " << u << " " << pre << " " << t << endl;
  return t <= theta;
}

bool can[20][20][20];

int main() {
  cin >> n >> r >> theta;

  theta *= 2 * PI / 360.0;

  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }

  for (int i = 0; i < 10010; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        dp[i][j][k] = INF;
      }
    }
  }

  for (int v = 0; v < n; v++) {
    for (int u = 0; u < n; u++) {
      for (int pre = 0; pre < n; pre++) {
        if (v == u)
          continue;
        can[v][u][pre] = check(v, u, pre);
      }
    }
  }

  // cout << check(2, 0, 1) << endl;
  // return 0;

  dp[0][0][0] = 0;
  for (int i = 0; i <= 10000; i++) {
    for (int v = 0; v < n; v++) {
      for (int pre = 0; pre < n; pre++) {
        double d = dp[i][v][pre];
        if (d >= 1e14)
          continue;
        // cerr << i << " " << v << " " << pre << " " << d << endl;
        for (int u = 0; u < n; u++) {
          if (v == u)
            continue;
          if (i != 0 && !can[v][u][pre])
            continue;
          // cerr << "\\t" << v << " " << u << endl;
          double ndist = d + dist(x[v], y[v], x[u], y[u]);
          if (ndist <= r && dp[i + 1][u][v] > ndist) {
            dp[i + 1][u][v] = ndist;
          }
        }
      }
    }
  }

  int ans = 0;
  for (int i = 0; i <= 10000; i++) {
    for (int v = 0; v < n; v++) {
      for (int pre = 0; pre < n; pre++) {
        double d = dp[i][v][pre];
        if (d >= 1e14)
          continue;
        ans = max(ans, i);
      }
    }
  }
  cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
const double PI = acos(-1);
const double INF = 1e15;
double dp[10010][20][20];

int n;
double r, theta;
double x[20], y[20];

double dist(double x1, double y1, double x2, double y2) {
  x1 -= x2, y1 -= y2;
  return sqrt(x1 * x1 + y1 * y1);
}

double dot(double x1, double y1, double x2, double y2) {
  return x1 * x2 + y1 * y2;
}

bool check(int v, int u, int pre) {
  double ax = x[v] - x[pre];
  double ay = y[v] - y[pre];
  double bx = x[u] - x[v];
  double by = y[u] - y[v];
  double da = dist(x[v], y[v], x[pre], y[pre]);
  double db = dist(x[u], y[u], x[v], y[v]);
  double t = abs(acos(dot(ax, ay, bx, by) / da / db));
  // cerr << "\\t\\t" << v << " " << u << " " << pre << " " << t << endl;
  return t <= theta;
}

int main() {
  cin >> n >> r >> theta;

  theta *= 2 * PI / 360.0;

  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }

  for (int i = 0; i < 10010; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        dp[i][j][k] = INF;
      }
    }
  }

  // cout << check(2, 0, 1) << endl;
  // return 0;

  dp[0][0][0] = 0;
  for (int i = 0; i <= 10000; i++) {
    for (int v = 0; v < n; v++) {
      for (int pre = 0; pre < n; pre++) {
        double d = dp[i][v][pre];
        if (d >= 1e14)
          continue;
        // cerr << i << " " << v << " " << pre << " " << d << endl;
        for (int u = 0; u < n; u++) {
          if (v == u)
            continue;
          if (i != 0 && !check(v, u, pre))
            continue;
          // cerr << "\\t" << v << " " << u << endl;
          double ndist = d + dist(x[v], y[v], x[u], y[u]);
          if (ndist <= r && dp[i + 1][u][v] > ndist) {
            dp[i + 1][u][v] = ndist;
          }
        }
      }
    }
  }

  int ans = 0;
  for (int i = 0; i <= 10000; i++) {
    for (int v = 0; v < n; v++) {
      for (int pre = 0; pre < n; pre++) {
        double d = dp[i][v][pre];
        if (d >= 1e14)
          continue;
        ans = max(ans, i);
      }
    }
  }
  cout << ans << endl;
}