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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <list>
#include <map>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define SUPwl 16
#define UNDEFCHAN 2 * pow(10, 10)
#define EPS 1 * pow(1, -10)
#define EQ(a, b) (fabs(a - b) < EPS)

struct W {
  int n, d, r; // name, distance from main castle, number of senryobako
};
typedef vector<int> Path;
struct TandP {
  double t;
  Path p;
  TandP() {
    t = UNDEFCHAN;
    p = Path();
  }
};

int wl;
W wos[SUPwl];
TandP memf[1 << SUPwl][SUPwl];

double getV(int s) {
  double m = 0;
  FOR(wi, 0, wl) {
    if (s >> wi & 1)
      m += 20.0 * wos[wi].r;
  }
  return 2000.0 / (70.0 + m);
}

TandP f(int s, int wi) {
  if (!EQ(memf[s][wi].t, UNDEFCHAN)) {
    return memf[s][wi];
  }

  TandP re = TandP();
  if (s == (1 << wl) - 1) {
    re.t = 0;
    re.p.push_back(wi);
  } else {
    FOR(bwi, 0, wl) {
      if (s & (1 << bwi))
        continue;
      if (bwi == wi)
        continue;
      TandP bre = f(s + (1 << bwi), bwi);
      double nret = bre.t + fabs(wos[wi].d - wos[bwi].d) / getV(s);
      if (re.t > nret) {
        re.t = nret;
        re.p.clear();
        copy(bre.p.begin(), bre.p.end(), back_inserter(re.p));
        re.p.push_back(wi);
      }
    }
  }
  // cout<<s<<" "<<wi<<" "<<re.t<<endl;
  memf[s][wi] = re;
  return re;
}

Path solve() {
  FOR(s, 0, 1 << wl) FOR(wi, 0, wl) memf[s][wi] = TandP();

  double ret = UNDEFCHAN;
  Path rep = Path();
  FOR(bwi, 0, wl) {
    TandP bre = f(1 << bwi, bwi);
    if (ret > bre.t) {
      ret = bre.t;
      // cout<<0<<" "<<bwi<<" "<<ret<<endl;
      rep.clear();
      copy(bre.p.begin(), bre.p.end(), back_inserter(rep));
    }
  }
  return rep;
}

int main() {
  cin >> wl;
  FOR(wi, 0, wl) cin >> wos[wi].n >> wos[wi].d >> wos[wi].r;
  Path rep = solve();
  for (int wi = rep.size() - 1; wi > 0; --wi) {
    cout << wos[rep[wi]].n << " ";
  }
  cout << wos[rep[0]].n << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <list>
#include <map>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define SUPwl 16
#define UNDEFCHAN 2 * pow(10, 10)
#define EPS 1 * pow(1, -10)
#define EQ(a, b) (fabs(a - b) < EPS)

struct W {
  int n, d, r; // name, distance from main castle, number of senryobako
};
typedef vector<W> Path;
struct TandP {
  double t;
  Path p;
  TandP() {
    t = UNDEFCHAN;
    p = Path();
  }
};

int wl;
W wos[SUPwl];
TandP memf[1 << SUPwl][SUPwl];

double getV(int s) {
  double m = 0;
  FOR(wi, 0, wl) {
    if (s >> wi & 1)
      m += 20.0 * wos[wi].r;
  }
  return 2000.0 / (70.0 + m);
}

TandP f(int s, int wi) {
  if (!EQ(memf[s][wi].t, UNDEFCHAN)) {
    return memf[s][wi];
  }

  TandP re = TandP();
  if (s == (1 << wl) - 1) {
    re.t = 0;
    re.p.push_back(wos[wi]);
  } else {
    FOR(bwi, 0, wl) {
      if (s & (1 << bwi))
        continue;
      if (bwi == wi)
        continue;
      TandP bre = f(s + (1 << bwi), bwi);
      double nret = bre.t + fabs(wos[wi].d - wos[bwi].d) / getV(s);
      if (re.t > nret) {
        re.t = nret;
        re.p.clear();
        copy(bre.p.begin(), bre.p.end(), back_inserter(re.p));
        re.p.push_back(wos[wi]);
      }
    }
  }
  cout << s << " " << wi << " " << re.t << endl;
  memf[s][wi] = re;
  return re;
}

Path solve() {
  FOR(s, 0, 1 << wl) FOR(wi, 0, wl) memf[s][wi] = TandP();

  double ret = UNDEFCHAN;
  Path rep = Path();
  FOR(bwi, 0, wl) {
    TandP bre = f(1 << bwi, bwi);
    if (ret > bre.t) {
      ret = bre.t;
      cout << 0 << " " << bwi << " " << ret << endl;
      rep.clear();
      copy(bre.p.begin(), bre.p.end(), back_inserter(rep));
    }
  }
  return rep;
}

int main() {
  cin >> wl;
  FOR(wi, 0, wl) cin >> wos[wi].n >> wos[wi].d >> wos[wi].r;
  Path rep = solve();
  for (int wi = rep.size() - 1; wi > 0; --wi) {
    cout << rep[wi].n << " ";
  }
  cout << rep[0].n;
  return 0;
}