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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int, int> pint;
#define mp make_pair

template <class T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cout << *i << " ";
  cout << endl;
}
template <class T> void chmin(T &t, T f) {
  if (t > f)
    t = f;
}
template <class T> void chmax(T &t, T f) {
  if (t < f)
    t = f;
}
int in() {
  int x;
  scanf("%d", &x);
  return x;
}

vint x;
double n, dis[20][20];
int m;
string str;
double dp[5000][15];

void input() {
  int c;
  x.clear();
  m = 0;
  bool first = true;
  int num = 0;
  int i;
  for (i = 0; i < str.size(); i++) {
    c = str[i];
    if (c == ' ') {
      if (first) {
        n = num;
        num = 0;
        first = false;
      } else {
        x.push_back(num);
        m++;
        num = 0;
      }
    } else {
      num = num * 10 + c - '0';
    }
  }
  if (num != 0) {
    x.push_back(num);
    m++;
  }
  return;
}

void hoge(int i, int j) {
  // cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
  int k;
  double res = -2;
  if (dp[i][j] != -1)
    return;
  if (i & 1 << j) {
    int ii = i ^ 1 << j;
    for (k = 0; k < m; k++) {
      hoge(ii, k);
      // cout<<" "<<ii<<" "<<k<<" "<<dp[ii][k]<<" "<<x[j]<<" "<<x[k]<<endl;
      if (dp[ii][k] == -2)
        continue;
      else if (res == -2)
        res = dp[ii][k] + dis[x[j]][x[k]];
      else
        chmin(res, dp[ii][k] + dis[x[j]][x[k]]);
    }
  }
  dp[i][j] = res;
  // cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}

int main() {
  int i, j;
  for (i = 0; i < 20; i++) {
    for (j = 0; j < 20; j++) {
      dis[i][j] = sqrt(double((i + j) * (i + j) - (i - j) * (i - j)));
    }
  }
  while (getline(cin, str)) {
    input();
    int i;
    // for(i=0;i<m;i++)cout<<x[i]<<endl;
    for (i = 0; i < 5000; i++) {
      for (j = 0; j < 15; j++) {
        dp[i][j] = -1;
      }
    }
    for (i = 0; i < m; i++)
      dp[1 << i][i] = x[i];
    for (i = 0; i < m; i++) {
      hoge((1 << m) - 1, i);
      dp[(1 << m) - 1][i] += x[i];
    }
    double res = 100100100;
    for (i = 0; i < m; i++)
      chmin(res, dp[(1 << m) - 1][i]);
    cout << (n >= res ? "OK" : "NA") << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int, int> pint;
#define mp make_pair

template <class T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cout << *i << " ";
  cout << endl;
}
template <class T> void chmin(T &t, T f) {
  if (t > f)
    t = f;
}
template <class T> void chmax(T &t, T f) {
  if (t < f)
    t = f;
}
int in() {
  int x;
  scanf("%d", &x);
  return x;
}

vint x, k;
double n;
int m;
string str;

void input() {
  int c;
  x.clear();
  bool first = true;
  int num = 0;
  int i;
  for (i = 0; i < str.size(); i++) {
    c = str[i];
    if (c == ' ') {
      if (first) {
        n = num;
        num = 0;
        first = false;
      } else {
        x.push_back(num);
        m++;
        num = 0;
      }
    } else {
      num = num * 10 + c - '0';
    }
  }
  if (num != 0) {
    x.push_back(num);
    m++;
  }
  return;
}

double dis[20][20];

double hoge() {
  double res = x[k[0]] + x[k[m - 1]];
  int i;
  for (i = 0; i < m - 1; i++) {
    res += dis[x[k[i]]][x[k[i + 1]]];
  }
  return res;
}

int main() {
  double ii, jj;
  for (ii = 0; ii < 20; ii++) {
    for (jj = 0; jj < 20; jj++) {
      dis[(int)ii][(int)jj] =
          sqrt((ii + jj) * (ii + jj) - (ii - jj) * (ii - jj));
    }
  }
  while (getline(cin, str)) {
    int i;
    x.clear();
    k.clear();
    m = 0;
    input();
    for (i = 0; i < m; i++)
      k.push_back(i);
    double res = 10000;
    do {
      chmin(res, hoge());
    } while (next_permutation(k.begin(), k.end()));
    cout << (res <= n ? "OK" : "NO") << endl;
  }
  return 0;
}