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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef short INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

typedef long long LL;
const int SIZE = 16;
const int BIT_SIZE = 1 << SIZE;
typedef pair<double, VI> DATA;
const double INF = 999999999.0;

int n;
LL NO[SIZE], D[SIZE], K[SIZE];
LL W[BIT_SIZE];
DATA dp1[SIZE][BIT_SIZE];

void init() {
  for (int i = 0; i < SIZE; ++i) {
    for (int j = 0; j < BIT_SIZE; ++j) {
      dp1[i][j] = DATA(INF, VI());
    }
  }
}

DATA solve(int k, int state, double weight) {
  DATA res(0, VI());
  res.second.push_back(k);

  if (state == (1 << n) - 1)
    return res;
  if (dp1[k][state].first != INF)
    return dp1[k][state];

  res.first = INF;
  for (int i = 0; i < n; ++i) {
    if ((state & (1 << i)) != 0)
      continue;
    DATA ret = solve(i, state | (1 << i), weight + K[i]);
    ret.first += abs(D[k] - D[i]) / (2000.0 / (70.0 + weight));
    if (res.first > ret.first)
      res = ret;
  }

  res.second.insert(res.second.begin(), k);
  return dp1[k][state] = res;
}

void output(DATA data) {
  for (int i = 0; i < n; ++i) {
    cout << NO[data.second[i]];
    if (i + 1 < n)
      cout << " ";
  }
  cout << endl;
}

int main() {
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> NO[i] >> D[i] >> K[i];
    K[i] *= 20;
  }
  init();
  DATA res(INF, VI());
  for (int i = 0; i < n; ++i) {
    DATA ret = solve(i, 1 << i, K[i]);
    if (res.first > ret.first)
      res = ret;
  }
  output(res);
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

typedef long long LL;
const int SIZE = 16;
const int BIT_SIZE = 1 << SIZE;
typedef pair<double, VI> DATA;
const LL INF = 10000000000LL;

int n;
LL NO[SIZE], D[SIZE], K[SIZE];
LL W[BIT_SIZE];
DATA dp1[SIZE][BIT_SIZE];
double minCost;
VI minPath;

void init() {
  minCost = -1.0;
  fill((DATA *)dp1, (DATA *)dp1 + SIZE * BIT_SIZE, DATA(INF, VI()));
}

DATA solve(int k, int state, double weight) {
  DATA &res = dp1[k][state];
  if (res.first != INF)
    return res;

  res = DATA(0, VI());
  res.second.push_back(k);
  if (state == (1 << n) - 1)
    return res;

  res.first = INT_MAX;
  for (int i = 0; i < n; ++i) {
    int bi = 1 << i;
    if ((state & bi) != 0)
      continue;
    int newState = state | bi;
    DATA ret = solve(i, newState, weight + K[i]);
    ret.first += (double)abs(D[k] - D[i]) / (2000.0 / (70.0 + weight));
    res = min(res, ret);
  }

  res.second.insert(res.second.begin(), k);
  return res;
}

void output(DATA data) {
  for (int i = 0; i < n; ++i) {
    cout << NO[data.second[i]];
    if (i + 1 < n)
      cout << " ";
  }
  cout << endl;
}

int main() {
  while (cin >> n) {
    for (int i = 0; i < n; ++i) {
      cin >> NO[i] >> D[i] >> K[i];
    }
    for (int i = 0; i < (1 << n); ++i) {
      int w = 0;
      for (int j = 0; j < n; ++j) {
        if ((i & (1 << j)) == 0)
          continue;
        w += K[j];
      }
      W[i] = w * 20;
    }
    init();
    DATA res(INF, VI());
    for (int i = 0; i < n; ++i) {
      DATA ret = solve(i, 1 << i, 0.0);
      res = min(res, ret);
    }
    output(res);
  }
  return 0;
}