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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define lengthof(array) (sizeof(array) / sizeof(*array))
#define dump(a) (cerr << (#a) << " = " << (a) << endl)
#define FOR(it, c)                                                             \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define RFOR(it, c)                                                            \\
  for (__typeof((c).rbegin()) it = (c).rbegin(); it != (c).rend(); ++it)

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
  return os;
}

#define MAX 16

int m, n;
double win[MAX][MAX];
double memo[MAX][(1 << MAX)];

inline double dfs(int room = 0, int rest = (1 << m) - 1) {
  if (memo[room][rest] >= 0.0)
    return memo[room][rest];

  double res = 0.0;
  for (int i = 0; i < m; ++i) {
    if (rest & (1 << i)) {
      const int next_rest = rest ^ (1 << i);
      double tmp = 0.0, p = 1.0;
      for (int j = room; j < n; ++j) {
        tmp += p * (1 - win[i][j]) * dfs(j, next_rest);
        p *= win[i][j];
      }

      chmax(res, tmp + p);
    }
  }

  return memo[room][rest] = res;
}

int main() {
  scanf("%d %d", &m, &n);

  for (int i = 0; i < m; ++i)
    for (int j = 0; j < n; ++j)
      scanf("%lf", &win[i][j]);

  memset(memo, -1, sizeof(memo));
  for (int i = 0; i < n; ++i)
    memo[i][0] = 0.0;

  printf("%.15lf\\n", dfs());

  return EXIT_SUCCESS;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define lengthof(array) (sizeof(array) / sizeof(*array))
#define dump(a) (cerr << (#a) << " = " << (a) << endl)
#define FOR(it, c)                                                             \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define RFOR(it, c)                                                            \\
  for (__typeof((c).rbegin()) it = (c).rbegin(); it != (c).rend(); ++it)

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
  return os;
}

const int MAX = 16;
int m, n;
double win[MAX][MAX];
double memo[MAX][MAX][(1 << MAX)];

inline double dfs(int cat, int room, int used) {
  if (room == n)
    return 1.0;

  if (memo[cat][room][used] >= 0.0)
    return memo[cat][room][used];

  double res = 0.0;
  res += win[cat][room] * dfs(cat, room + 1, used);
  double mx = 0.0;
  for (int i = 0; i < m; ++i) {
    if ((used >> i) & 1)
      continue;

    chmax(mx, dfs(i, room, (used | (1 << i))));
  }

  res += mx * (1 - win[cat][room]);
  return memo[cat][room][used] = res;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> m >> n;

  for (int i = 0; i < m; ++i)
    for (int j = 0; j < n; ++j)
      cin >> win[i][j];

  memset(memo, -1, sizeof(memo));
  double ans = 0.0;
  for (int i = 0; i < m; ++i)
    chmax(ans, dfs(i, 0, (1 << i)));

  cout << ans << endl;

  return EXIT_SUCCESS;
}