Problem p00232 (C++) — buggy submission, verdict: Runtime Error

#include <cstring>
#include <iostream>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)

int X, Y, Z;
int V[4];
struct Cell {
  int N, E, A;
};
Cell cells[51];

float dp[51][50 * 100];

int main() {
  while (true) {
    cin >> X >> Y >> Z;
    if (!X && !Y && !Z)
      break;

    rep(i, X) cin >> V[i];

    memset(cells, 0, sizeof(int) * 3 * (Y + 1));
    rep(i, Z) {
      Cell cell;
      cin >> cell.N >> cell.E >> cell.A;
      cells[cell.N] = cell;
    }

    rep(i, Y + 1) {
      rep(j, 100 * Y) { dp[i][j] = 0.0; }
    }
    dp[0][0] = 1.0;

    rep(i, Y) {
      rep(j, 100 * Y) {
        if (dp[i][j] == 0.0)
          continue;

        rep(k, X) {
          int money = j, current = i + V[k];
          if (current > Y)
            current = Y;
          Cell &cell = cells[current];
          switch (cell.E) {
          case 1:
            current += cell.A;
            break;
          case 2:
            money += cell.A;
            break;
          case 3:
            money -= cell.A;
            if (money < 0)
              money = 0;
            break;
          }
          if (current > Y)
            current = Y;
          dp[current][money] += dp[i][j] / X;
        }
      }
    }
    /*
    rep(i, Y + 1) {
        rep(j, 101) {
            cout.width(4);
            cout << dp[i][j];
        }
        cout << endl;
    }
    */

    float ans = 0.0;
    rep(i, 100 * Y) { ans += dp[Y][i] * i; }
    cout << (int)ans << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)

int X, Y, Z;

// vector<int> V;
int V[4];
struct Cell {
  int N, E, A;
};
// vector<Cell> cells;
Cell cells[51];

float memo[50][100 * 50];
// map<pair<int, int>, float> memo;

float rec(int current, long long patternNum, int money) {

  // cout << current << ' ' << patternNum << endl;

  if (memo[current][money] >= 0) {
    // pair<int, int> p(current, money);
    // if(memo.find(p) != memo.end()) {
    // cout << "memo! " << memo[current][money] << endl;
    // return memo[p];
    return memo[current][money];
  }

  if (current >= Y) {
    // cout << "returned " << 1.0 * money / patternNum << endl;
    // cout << money << " " << patternNum << endl;
    return 1.0 * money / patternNum;
  }

  Cell &cell = cells[current];
  switch (cell.E) {
  case 1:
    current += cell.A;
    break;
  case 2:
    money += cell.A;
    break;
  case 3:
    money -= cell.A;
    if (money < 0)
      money = 0;
    break;
  }

  float ret = 0;
  rep(i, X) { ret += rec(current + V[i], patternNum * X, money); }
  // cout << "returned " << ret << endl;
  // p.first = current; p.second = money;
  // return memo[p] = ret;
  return memo[current][money] = ret;
}

int main() {

  while (true) {
    cin >> X >> Y >> Z;
    if (!X && !Y && !Z)
      break;

    rep(i, X) cin >> V[i];

    // Cell zero = {0, 0, 0};
    // cells = vector<Cell>(Y + 1, zero);
    memset(cells, 0, sizeof(int) * 3 * (Y + 1));
    rep(i, Z) {
      Cell cell;
      cin >> cell.N >> cell.E >> cell.A;
      cells[cell.N] = cell;
    }

    // memset(memo, -1, 50 * 100 * 50 * sizeof(float));
    rep(i, 50) {
      rep(j, 100 * 50) { memo[i][j] = -1.0; }
    }
    // memo = map<pair<int, int>, float>();

    cout << (int)rec(0, 1, 0) << endl;
  }

  return 0;
}