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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;

vector<vector<int>> flag((6000), vector<int>(1 << 9));
vector<vector<pair<double, double>>> memo((6000),
                                          vector<pair<double, double>>(1 << 9));
pair<double, double> operator+(const pair<double, double> &l,
                               const pair<double, double> &r) {
  return make_pair(l.first + r.first, l.second + r.second);
}

pair<double, double> solve(const int a_win, const vector<int> &as,
                           const vector<int> &bs, bitset<9> a_used,
                           bitset<9> b_used) {
  int a_id = a_win + 500 * a_used.count() + 500;
  int b_id = b_used.to_ulong();
  if (flag[a_id][b_id])
    return memo[a_id][b_id];
  else {
    flag[a_id][b_id] = true;
    pair<double, double> sum;
    int num = 0;
    for (int a_next = 0; a_next < 9; ++a_next) {
      for (int b_next = 0; b_next < 9; ++b_next) {
        if (!a_used[a_next] && !b_used[b_next]) {
          a_used[a_next] = true;
          b_used[b_next] = true;
          int next_a_win = a_win;
          if (as[a_next] > bs[b_next]) {
            next_a_win += as[a_next] + bs[b_next];
          } else {
            next_a_win -= as[a_next] + bs[b_next];
          }
          sum = sum + solve(next_a_win, as, bs, a_used, b_used);
          a_used[a_next] = false;
          b_used[b_next] = false;
          num++;
        }
      }
      if (!a_used[a_next])
        break;
    }

    if (num == 0) {
      if (a_win == 0) {
        return memo[a_id][b_id] = make_pair(0, 0);
      } else if (a_win > 0) {
        return memo[a_id][b_id] = make_pair(1, 0);
      } else {
        return memo[a_id][b_id] = make_pair(0, 1);
      }
    } else {
      return memo[a_id][b_id] = make_pair(sum.first / num, sum.second / num);
    }
  }
}
int main() {
  int T;
  cin >> T;
  while (T--) {
    for (int i = 0; i < (6000); ++i) {
      for (int j = 0; j < (1 << 9); ++j) {
        flag[i][j] = false;
      }
    }
    vector<int> as, bs;
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 9; ++j) {
        int c;
        cin >> c;
        if (i)
          bs.emplace_back(c);
        else
          as.emplace_back(c);
      }
    }
    bitset<9> bs_a, bs_b;
    int a_win = 0;
    auto per = solve(a_win, as, bs, bs_a, bs_b);
    cout << per.first << " " << per.second << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;

vector<vector<int>> flag((6000), vector<int>(1 << 9));
vector<vector<pair<double, double>>> memo((10000),
                                          vector<pair<double, double>>(1 << 9));
pair<double, double> operator+(const pair<double, double> &l,
                               const pair<double, double> &r) {
  return make_pair(l.first + r.first, l.second + r.second);
}

pair<double, double> solve(const int a_win, const vector<int> &as,
                           const vector<int> &bs, bitset<9> a_used,
                           bitset<9> b_used) {
  int a_id = a_win + 500 * a_used.count() + 500;
  int b_id = b_used.to_ulong();
  if (flag[a_id][b_id])
    return memo[a_id][b_id];
  else {
    flag[a_id][b_id] = true;
    pair<double, double> sum;
    int num = 0;
    for (int a_next = 0; a_next < 9; ++a_next) {
      for (int b_next = 0; b_next < 9; ++b_next) {
        if (!a_used[a_next] && !b_used[b_next]) {
          a_used[a_next] = true;
          b_used[b_next] = true;
          int next_a_win = a_win;
          if (as[a_next] > bs[b_next]) {
            next_a_win += as[a_next] + bs[b_next];
          } else {
            next_a_win -= as[a_next] + bs[b_next];
          }
          sum = sum + solve(next_a_win, as, bs, a_used, b_used);
          a_used[a_next] = false;
          b_used[b_next] = false;
          num++;
        }
      }
      if (!a_used[a_next])
        break;
    }

    if (num == 0) {
      if (a_win == 0) {
        return memo[a_id][b_id] = make_pair(0, 0);
      } else if (a_win > 0) {
        return memo[a_id][b_id] = make_pair(1, 0);
      } else {
        return memo[a_id][b_id] = make_pair(0, 1);
      }
    } else {
      return memo[a_id][b_id] = make_pair(sum.first / num, sum.second / num);
    }
  }
}
int main() {
  int T;
  cin >> T;
  while (T--) {
    for (int i = 0; i < (10000); ++i) {
      for (int j = 0; j < (1 << 9); ++j) {
        flag[i][j] = false;
      }
    }
    vector<int> as, bs;
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 9; ++j) {
        int c;
        cin >> c;
        if (i)
          bs.emplace_back(c);
        else
          as.emplace_back(c);
      }
    }
    bitset<9> bs_a, bs_b;
    int a_win = 0;
    auto per = solve(a_win, as, bs, bs_a, bs_b);
    cout << per.first << " " << per.second << endl;
  }
  return 0;
}