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

#include <iostream>
#include <stdio.h>

using namespace std;

int n, m;
int pt[3][2005];
int gain[] = {5, 3, 2};
double dp[2005][2005];
double dp2[2005][3];
double exp[3][2005];
double prob[2005];

int main(void) {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> pt[0][i] >> pt[1][i] >> pt[2][i];
  }

  dp[0][0] = 1;
  for (int i = 0; i < m; i++) {
    for (int j = 0; j <= m; j++) {
      if (j == m)
        dp[i + 1][j] += dp[i][j];
      else {
        dp[i + 1][j + 1] += dp[i][j] / 3.0;
        dp[i + 1][j] += dp[i][j] / 3.0 * 2;
      }
    }
  }
  double sum = 0;
  for (int i = 0; i <= m; i++) {
    sum += dp[m][i];
    prob[i] = sum;
  }

  double p, wp;
  for (int g = 0; g < 3; g++) {
    for (int x = 0; x <= m; x++) {

      for (int i = 0; i <= n; i++) {
        for (int j = 0; j < 3; j++) {
          dp2[i][j] = 0;
        }
      }
      dp2[1][0] = 1.0;

      wp = 1.0;
      for (int i = 1; i < n; i++) {
        int t = (pt[g][1] * x + pt[g][i + 1] - 1) / pt[g][i + 1] - 1;
        if (t > m)
          t = m;
        if (t < 0)
          p = 0;
        else
          p = prob[t];
        wp *= 1.0 - p;
        for (int j = 0; j < 3; j++) {
          dp2[i + 1][j] += p * dp2[i][j];
          if (j < 2)
            dp2[i + 1][j + 1] += (1.0 - p) * dp2[i][j];
        }
      }

      for (int i = 0; i < 3; i++)
        exp[g][x] += dp2[n][i];
      exp[g][x] *= gain[g];
      exp[g][x] -= wp;
    }
  }

  double ans = -1e18;
  for (int i = 0; i <= m; i++) {
    for (int j = 0; j <= m; j++) {
      int k = m - i - j;
      if (k < 0)
        continue;
      ans = max(ans, exp[0][i] + exp[1][j] + exp[2][k]);
    }
  }
  printf("%.11f\\n", ans);

  return 0;
}


Error: MLE

Fixed submission:

#include <iostream>
#include <stdio.h>

using namespace std;

int n, m;
int pt[3][2005];
int gain[] = {5, 3, 2};
double dp[2005][2005];
double dp2[3][2005][2005][3];
double exp[3][2005];
double prob[2005];

int main(void) {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> pt[0][i] >> pt[1][i] >> pt[2][i];
  }

  dp[0][0] = 1;
  for (int i = 0; i < m; i++) {
    for (int j = 0; j <= m; j++) {
      if (j == m)
        dp[i + 1][j] += dp[i][j];
      else {
        dp[i + 1][j + 1] += dp[i][j] / 3.0;
        dp[i + 1][j] += dp[i][j] / 3.0 * 2;
      }
    }
  }
  double sum = 0;
  for (int i = 0; i <= m; i++) {
    sum += dp[m][i];
    prob[i] = sum;
  }

  double p, wp;
  for (int g = 0; g < 3; g++) {
    for (int x = 0; x <= m; x++) {
      dp2[g][x][1][0] = 1.0;
      wp = 1.0;
      for (int i = 1; i < n; i++) {
        int t = (pt[g][1] * x + pt[g][i + 1] - 1) / pt[g][i + 1] - 1;
        if (t > m)
          t = m;
        if (t < 0)
          p = 0;
        else
          p = prob[t];
        wp *= 1.0 - p;
        for (int j = 0; j < 3; j++) {
          dp2[g][x][i + 1][j] += p * dp2[g][x][i][j];
          if (j < 2)
            dp2[g][x][i + 1][j + 1] += (1.0 - p) * dp2[g][x][i][j];
        }
      }

      for (int i = 0; i < 3; i++)
        exp[g][x] += dp2[g][x][n][i];
      exp[g][x] *= gain[g];
      exp[g][x] -= wp;
    }
  }

  double ans = -1e18;
  for (int i = 0; i <= m; i++) {
    for (int j = 0; j <= m; j++) {
      int k = m - i - j;
      if (k < 0)
        continue;
      ans = max(ans, exp[0][i] + exp[1][j] + exp[2][k]);
    }
  }
  printf("%.11f\\n", ans);

  return 0;
}