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

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

int n, m;
vector<short> point[3];
ld p[2222], win[2222][2222];
ld dp[2222][2222][4], exper[3][2222];
ld score[] = {5, 3, 2};

ld calc(int m, int i) {
  ld res = 1.0;
  int a = m - i;
  REP(j, i) {
    res *= ld(m - j);
    res /= ld(j + 1);
    res /= 3.0;
    if (a > 0) {
      res *= 2.0 / 3.0;
      a--;
    }
  }
  while (a > 0) {
    res *= 2.0 / 3.0;
    a--;
  }
  return res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  cin >> n >> m;
  REP(i, 3) point[i].resize(n);
  REP(i, m + 1) { p[i] = calc(m, i); }
  for (int i = m - 1; i >= 0; i--)
    p[i] += p[i + 1];
  REP(i, n) REP(j, 3) cin >> point[j][i];
  REP(i, 3) {
    REP(j, m + 1) FOR(k, 1, n) {
      int need;
      int my = j * point[i][0];
      if (my % point[i][k] == 0)
        need = my / point[i][k];
      else
        need = my / point[i][k] + 1;
      win[j][k] = 1 - p[min(need, m + 1)];
    }
    REP(j, 2222) REP(k, 2222) REP(l, 4) dp[j][k][l] = 0.0;
    REP(j, 2222) dp[j][0][0] = dp[j][0][3] = 1.0;
    REP(j, m + 1) {
      FOR(k, 1, n) {
        REP(l, 3) {
          dp[j][k][l] += dp[j][k - 1][l] * win[j][k];
          if (l != 2)
            dp[j][k][l + 1] += dp[j][k - 1][l] * (1 - win[j][k]);
          if (dp[j][k][l] < EPS)
            dp[j][k][l] = 0;
        }
        dp[j][k][3] = dp[j][k - 1][3] * (1 - win[j][k]);
        if (dp[j][k][3] < EPS)
          dp[j][k][3] = 0;
      }
    }
    REP(j, m + 1)
    exper[i][j] =
        (dp[j][n - 1][0] + dp[j][n - 1][1] + dp[j][n - 1][2]) * score[i] -
        dp[j][n - 1][3];
  }
  ld ans = -INF;
  REP(i, m + 1) REP(j, m + 1) {
    int k = m - i - j;
    if (k < 0)
      continue;
    ld tmp = exper[0][i] + exper[1][j] + exper[2][k];
    chmax(ans, tmp);
  }
  cout << ans << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

int n, m;
vector<short> point[3];
ld p[2222], win[3][2222][2222];
ld dp[2222][2222][4], exper[3][2222];
ld score[] = {5, 3, 2};

ld comb(int n, int k) {
  ld res = 1.0;
  REP(i, k) {
    res *= ld(n - i);
    res /= ld(i + 1);
  }
  return res;
}

ld calc(int m, int i) {
  ld res = 1.0;
  int a = m - i;
  REP(j, i) {
    res *= ld(m - j);
    res /= ld(j + 1);
    res /= 3.0;
    if (a > 0) {
      res *= 2.0 / 3.0;
      a--;
    }
  }
  while (a > 0) {
    res *= 2.0 / 3.0;
    a--;
  }
  return res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  cin >> n >> m;
  REP(i, 3) point[i].resize(n);
  REP(i, m + 1) { /*
                         p[i] = comb(m, i);
                         REP(j, i) p[i] /= 3.0;
                         REP(j, m - i) p[i] *= 2.0 / 3.0;
                         if (p[i] < EPS) p[i] = 0;*/
    p[i] = calc(m, i);
  }
  for (int i = m - 1; i >= 0; i--)
    p[i] += p[i + 1];
  REP(i, n) REP(j, 3) cin >> point[j][i];
  REP(i, 3) REP(j, m + 1) FOR(k, 1, n) {
    int need;
    int my = j * point[i][0];
    if (my % point[i][k] == 0)
      need = my / point[i][k];
    else
      need = my / point[i][k] + 1;
    win[i][j][k] = 1 - p[min(need, m + 1)];
  }
  REP(i, 3) {
    REP(j, 2222) REP(k, 2222) REP(l, 4) dp[j][k][l] = 0.0;
    REP(j, 2222) dp[j][0][0] = dp[j][0][3] = 1.0;
    REP(j, m + 1) {
      FOR(k, 1, n) {
        REP(l, 3) {
          dp[j][k][l] += dp[j][k - 1][l] * win[i][j][k];
          if (l != 2)
            dp[j][k][l + 1] += dp[j][k - 1][l] * (1 - win[i][j][k]);
          if (dp[j][k][l] < EPS)
            dp[j][k][l] = 0;
        }
        dp[j][k][3] = dp[j][k - 1][3] * (1 - win[i][j][k]);
        if (dp[j][k][3] < EPS)
          dp[j][k][3] = 0;
      }
    }
    REP(j, m + 1)
    exper[i][j] =
        (dp[j][n - 1][0] + dp[j][n - 1][1] + dp[j][n - 1][2]) * score[i] -
        dp[j][n - 1][3];
  }
  ld ans = -INF;
  REP(i, m + 1) REP(j, m + 1) {
    int k = m - i - j;
    if (k < 0)
      continue;
    ld tmp = exper[0][i] + exper[1][j] + exper[2][k];
    chmax(ans, tmp);
  }
  cout << ans << endl;
  return 0;
}