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

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include "bits/stdc++.h"
using namespace std;
#define REP(i, a, b) for (int i = a; i < b; ++i)
#define rep(i, n) REP(i, 0, n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define all(a) begin(a), end(a)
#define ifnot(a) if (not(a))
#define dump(x) cerr << #x << " = " << (x) << endl
// #define int ll
#ifdef _MSC_VER
const bool test = true;
#else
const bool test = false;
#endif

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

int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
const int INF = 1 << 28;
const ll INFL = (ll)1 << 58;
ll mod = (int)1e9 + 7;

//.....................
const int MAX = (int)2e5 + 5;

char s_[MAX];
int n, m;
double board[20][20];

double dfs(int reached) {
  static int used;
  static double dp[1 << 17][20];
  static bool done[1 << 18][20];
  if (done[used][reached] == true) {
    return dp[used][reached];
  }
  double res = 0.0;
  if (reached == n) {
    return 1.0;
    if (test)
      cerr << "!";
  }
  rep(i, m) {
    if ((used >> i) & 1)
      continue;
    used |= 1 << i;
    double res_i = 0.0;
    double keep_win_p = 1.0;
    REP(j, reached, n) {
      res_i += dfs(j) * keep_win_p * (1.0 - board[i][j]);
      if (test)
        dump(dfs(j));
      keep_win_p *= board[i][j];
    }
    res_i += keep_win_p;
    chmax(res, res_i);
    used ^= 1 << i;
  }
  done[used][reached] = true;
  return dp[used][reached] = res;
}

void solve() {
  // m = atoi(s_);
  cin >> m;
  cin >> n;
  rep(i, m) rep(j, n) cin >> board[i][j];
  cout << dfs(0) << endl;
}

signed main() {
  int T = 10;
  cout << fixed << setprecision(15);
  rep(i, T) {
    // if (scanf("%s", s_) == EOF) break;
    solve();
    break;
  }
  return 0;
}

Error: MLE

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include "bits/stdc++.h"
using namespace std;
#define REP(i, a, b) for (int i = a; i < b; ++i)
#define rep(i, n) REP(i, 0, n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define all(a) begin(a), end(a)
#define ifnot(a) if (not(a))
#define dump(x) cerr << #x << " = " << (x) << endl
// #define int ll
#ifdef _MSC_VER
const bool test = true;
#else
const bool test = false;
#endif

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

int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
const int INF = 1 << 28;
const ll INFL = (ll)1 << 58;
ll mod = (int)1e9 + 7;

//.....................
const int MAX = (int)2e5 + 5;

char s_[MAX];
int n, m;
double board[20][20];
map<pair<vector<int>, int>, double> dp;
map<pair<vector<int>, int>, bool> done;

double dfs(int reached) {
  // static double dp[1 << 18];
  // static bool done[1 << 18];
  static vector<int> used(20);
  pair<vector<int>, int> cur_status = {used, reached};
  if (done[cur_status] == true) {
    return dp[cur_status];
  }
  double res = 0.0;
  if (reached == n) {
    return 1.0;
    if (test)
      cerr << "!";
  }
  rep(i, m) {
    if (used[i])
      continue;
    used[i] = true;
    double res_i = 0.0;
    double keep_win_p = 1.0;
    REP(j, reached, n) {
      res_i += dfs(j) * keep_win_p * (1.0 - board[i][j]);
      if (test)
        dump(dfs(j));
      keep_win_p *= board[i][j];
    }
    res_i += keep_win_p;
    chmax(res, res_i);
    used[i] = false;
  }
  done[cur_status] = true;
  return dp[cur_status] = res;
}

void solve() {
  // m = atoi(s_);
  cin >> m;
  cin >> n;
  rep(i, m) rep(j, n) cin >> board[i][j];
  cout << dfs(0) << endl;
}

signed main() {
  int T = 10;
  cout << fixed << setprecision(15);
  rep(i, T) {
    // if (scanf("%s", s_) == EOF) break;
    solve();
    break;
  }
  return 0;
}