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

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>

#include <cstdio>
using namespace std;

typedef struct {
  int idx, dist, num;
} Store;

const double INF = 1e20;

int n, dist[16][16], weight[1 << 15];
pair<double, int> dp[1 << 15][16];

pair<double, int> solve(int S, int p) {
  if (S == (1 << n) - 1)
    return make_pair(0.0, -1);

  if (dp[S][p].first != INF)
    return dp[S][p];

  pair<double, int> res(INF, -1);
  for (int i = 0; i < n; ++i) {
    if (!(S & (1 << i))) {
      pair<double, int> tmp = solve(S | (1 << i), i);
      tmp.first += dist[p][i] / (2000.0 / (70.0 + weight[S]));
      if (tmp.first < res.first) {
        res.first = tmp.first;
        res.second = i;
      }
    }
  }
  return dp[S][p] = res;
}

int main() {
  while (cin >> n) {
    vector<Store> store(n);
    for (int i = 0; i < n; ++i)
      cin >> store[i].idx >> store[i].dist >> store[i].num;

    for (int i = 0; i < n; ++i) {
      for (int j = i + 1; j < n; ++j)
        dist[i][j] = dist[j][i] = 60 * abs(store[i].dist - store[j].dist);
      dist[n][i] = 0;
    }

    for (int S = 0; S < (1 << n); ++S) {
      weight[S] = 0;
      for (int i = 0; i < n; ++i) {
        if (S & (1 << i))
          weight[S] += store[i].num;
      }
      weight[S] *= 20;
    }

    for (int S = 0; S < (1 << n); ++S) {
      for (int i = 0; i <= n; ++i)
        dp[S][i].first = INF;
    }

    solve(0, n);

    int S = 0, p = n;
    vector<int> ans;
    while (S != (1 << n) - 1) {
      int next = dp[S][p].second;
      S |= (1 << next);
      p = next;
      ans.push_back(store[next].idx);
    }

    for (int i = 0; i < ans.size() - 1; ++i)
      cout << ans[i] << " ";
    cout << ans.back() << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

typedef struct {
  int idx, dist, num;
} Store;

int n;
double min_time, dp[1 << 15][15];
vector<int> ans;

void solve(int S, int p, int w, double t, vector<int> &path,
           const vector<Store> &store, const vector<vector<int>> &dist) {
  if (S == (1 << n) - 1) {
    if (t < min_time) {
      min_time = t;
      ans = path;
    }
    return;
  }

  if (dp[S][p] < t)
    return;

  dp[S][p] = t;
  for (int i = 0; i < n; ++i) {
    if (!(S & (1 << i))) {
      path.push_back(store[i].idx);
      double tt = dist[p][i] / ((2000.0 / (70.0 + 20.0 * w)) / 60.0);
      solve(S | (1 << i), i, w + store[i].num, t + tt, path, store, dist);
      path.pop_back();
    }
  }
  return;
}

int main() {
  while (cin >> n) {
    vector<Store> store(n);
    for (int i = 0; i < n; ++i)
      cin >> store[i].idx >> store[i].dist >> store[i].num;

    vector<vector<int>> dist(n + 1, vector<int>(n + 1, 0));
    for (int i = 0; i < n; ++i) {
      for (int j = i + 1; j < n; ++j)
        dist[i][j] = dist[j][i] = abs(store[i].dist - store[j].dist);
      dist[n][i] = 0;
    }

    min_time = 1e20;
    ans.clear();
    vector<int> tmp;
    for (int i = 0; i < (1 << 15); ++i) {
      for (int j = 0; j < 15; ++j)
        dp[i][j] = 1e20;
    }
    solve(0, n, 0, 0.0, tmp, store, dist);
    for (int i = 0; i < ans.size() - 1; ++i)
      cout << ans[i] << " ";
    cout << ans.back() << endl;
  }
  return 0;
}