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

#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) static_cast<bitset<16>>(x)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i, m, n) for (int i = m; i < (int)(n); i++)
#define if_range(x, y, w, h)                                                   \\
  if (0 <= (int)(x) && (int)(x) < (int)(w) && 0 <= (int)(y) &&                 \\
      (int)(y) < (int)(h))
#define ALL(a) (a).begin(), (a).end()
const int INF = 1e9;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

/* struct P {
        int x, y, n;
        P(int n, int x, int y):n(n), x(x), y(y){}
        P(){}
}; */

/** Problem0232 : Life Game **/
int X, Y;
int getm[110], prog[110];
vector<int> rou;

// dp[i][j] := j円持ってiマス目に止まる確率
double dp[101][5001];

int main() {
  int Z;
  while (cin >> X >> Y >> Z, X) {
    memset(getm, 0, sizeof(getm));
    memset(prog, 0, sizeof(prog));

    rou.resize(X);
    rep(i, X) cin >> rou[i];

    rep(i, Z) {
      int a, b, c;
      cin >> a >> b >> c;
      if (b == 1) {
        prog[a] = c;
      } else {
        getm[a] = c * (b == 2 ? 1 : -1);
      }
    }

    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1.0;
    for (int i = 0; i < Y; i++) {
      for (int j = 0; j <= 5000; j++) {
        for (int k = 0; k < X; k++) {
          int nc = i + rou[k];
          dp[min(Y, nc + prog[nc])][max(0, j + getm[nc])] += dp[i][j] / X;
        }
      }
    }

    double ans = 0;
    for (int j = 0; j <= 5000; j++) {
      ans += dp[Y][j] * j;
    }

    cout << (int)ans << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) static_cast<bitset<16>>(x)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i, m, n) for (int i = m; i < (int)(n); i++)
#define if_range(x, y, w, h)                                                   \\
  if (0 <= (int)(x) && (int)(x) < (int)(w) && 0 <= (int)(y) &&                 \\
      (int)(y) < (int)(h))
#define ALL(a) (a).begin(), (a).end()
const int INF = 1e9;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

/* struct P {
        int x, y, n;
        P(int n, int x, int y):n(n), x(x), y(y){}
        P(){}
}; */

/** Problem0232 : Life Game **/
int X, Y;
int getm[110], prog[110];
vector<int> rou;

double dp[110][10010][110];

double solve(int n, int money, int d) {
  if (n >= Y)
    return money / pow(X, d);
  if (dp[n][money][d] > 0)
    return dp[n][money][d];

  double res = 0;
  for (int i = 0; i < X; i++) {
    int ncell = n + rou[i];
    res += solve(ncell + prog[ncell], max(0, money + getm[ncell]), d + 1);
  }

  return dp[n][money][d] = res;
}

int main() {
  int Z;
  while (cin >> X >> Y >> Z, X) {
    memset(dp, -1, sizeof(dp));
    memset(getm, 0, sizeof(getm));
    memset(prog, 0, sizeof(prog));

    rou.resize(X);
    rep(i, X) cin >> rou[i];

    rep(i, Z) {
      int a, b, c;
      cin >> a >> b >> c;
      if (b == 1) {
        prog[a] = c;
      } else {
        getm[a] = c * (b == 2 ? 1 : -1);
      }
    }

    cout << (int)solve(0, 0, 0) << endl;
  }
}