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

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

#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
#define foreach(c, i)                                                          \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

int c0[10], c1[10];

int main() {
  int T;
  scanf("%d", &T);
  while (T--) {
    rep(i, 9) scanf("%d", c0 + i);
    rep(i, 9) scanf("%d", c1 + i);

    const unsigned all = 362880;
    unsigned wins = 0;
    // prev 固定
    sort(c1, c1 + 9);
    do {
      unsigned pt = 0;
      rep(i, 9) if (c0[i] > c1[i]) pt += c0[i] + c1[i];
      if (pt > 85)
        ++wins;
    } while (next_permutation(c1, c1 + 9));
    double prob = (double)wins / all;
    printf("%.5f %.5f\\n", prob, 1 - prob);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
#define foreach(c, i)                                                          \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

int v0[10], v1[10];
const int half = 86, full = (1 << 9) - 1;
unsigned long dp[(1 << 9) + 2][(1 << 9) + 2];
struct tri {
  unsigned long e0, e1, e2;
};

inline int count_bit(const int num) {
  int cnt = 0;
  for (int i = 0; i < 9; ++i)
    if (num >> i & 1)
      ++cnt;
  return cnt;
}

int main() {
  int T;
  scanf("%d", &T);
  while (T--) {
    rep(i, 9) scanf("%d", v0 + i);
    rep(i, 9) scanf("%d", v1 + i);
    memset(dp, 0, sizeof dp);

    typedef pair<int, int> P;

    vector<map<P, unsigned long>> recs(half + 1);
    vector<unsigned long> ans(half + 1, 0);
    recs[0].insert(make_pair(P(0, 0), 1));
    unsigned long cnt = 0;
    for (int p = 0; p <= half; ++p) {
      memset(dp, 0, sizeof dp);
      if (p)
        recs[p - 1].clear();
      foreach (recs[p], it) {
        P p = it->first;
        dp[p.first][p.second] = it->second;
      }

      for (int n = 0; n < 9; ++n) {
        for (int S = 0; S < full; ++S) {
          if (n != count_bit(S))
            continue;
          for (int E = 0; E < full; ++E) {
            if (n != count_bit(E))
              continue;
            if (dp[S][E] == 0)
              continue;
            rep(i, 9) {
              if (S >> i & 1)
                continue;
              rep(j, 9) {
                if (E >> j & 1)
                  continue;
                ++cnt;
                int nextP = p + ((v0[i] > v1[j]) ? v0[i] + v1[j] : 0);
                nextP = min(nextP, half);

                if (((S | (1 << i)) == full) && ((E | (1 << j)) == full)) {
                  ans[nextP] += dp[S][E];
                  continue;
                }

                if (nextP > p) {
                  P nextKey = P(S | (1 << i), E | (1 << j));
                  if (recs[nextP].count(nextKey)) {
                    recs[nextP][nextKey] += dp[S][E];
                  } else {
                    recs[nextP].insert(make_pair(nextKey, dp[S][E]));
                  }
                } else if (nextP == p) {
                  dp[S | (1 << i)][E | (1 << j)] += dp[S][E];
                }
              }
            }
          }
        }
      }
    }

    unsigned long all = accumulate(ans.begin(), ans.end(), 0UL),
                  wins = ans[half];
    //     ans = dp[full][full];
    double prob = (double)wins / all;
    // printf("%lu %lu\\n", all, ans[half]);
    printf("%.5f %.5f\\n", prob, 1 - prob);
    // printf("%lu\\n", cnt);
  }

  return 0;
}