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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define MAXCOST 5000
double dp[51][MAXCOST + 1];
int v[4];
struct INFO {
  int type, val;
  INFO() {
    type = 0;
    val = 0;
  };
};
INFO mass[51];
int main() {
  int x, y, z;
  while (cin >> x >> y >> z, x) {
    rep(i, 51) mass[i] = INFO();
    rep(i, 51) rep(j, MAXCOST + 1) dp[i][j] = 0;
    rep(i, x) cin >> v[i];
    int mxcost = 0;
    rep(i, z) {
      int N;
      cin >> N;
      cin >> mass[N].type >> mass[N].val;
      if (mass[N].type == 2)
        mxcost += mass[N].val;
    }
    double baseProb = 1.0 / x;
    dp[0][0] = 1;
    for (int pos = 0; pos < y; pos++) {
      for (int cost = 0; cost <= mxcost; cost++) {
        rep(i, x) {
          int nextPos = pos + v[i];
          if (nextPos > y)
            nextPos = y;
          if (mass[nextPos].type == 0) {
            dp[nextPos][cost] += dp[pos][cost] * baseProb;
          }
          if (mass[nextPos].type == 1) {
            int newPos = nextPos + mass[nextPos].val;
            if (newPos > y)
              newPos = y;
            dp[newPos][cost] += dp[pos][cost] * baseProb;
          }
          if (mass[nextPos].type == 2) {
            int newCost = mass[nextPos].val + cost;
            dp[nextPos][newCost] += dp[pos][cost] * baseProb;
          }
          if (mass[nextPos].type == 3) {
            int newCost = cost - mass[nextPos].val;
            if (newCost < 0)
              newCost = 0;
            dp[nextPos][newCost] += dp[pos][cost] * baseProb;
          }
        }
      }
    }
    double sum = 0;
    for (int i = 0; i <= mxcost; i++) {
      sum += dp[y][i] * i;
    }
    cout << (int)sum << endl;
  }
}

Error: TLE

Fixed submission:

#include <iostream>

int x, y, z;
int invN, invE[51], invA[51], le[5];
double dp[5001][51];
double ans = 0;

using namespace std;

void life(int m, int n) {
  int a, c;
  int next, gm;
  int flag = 1;
  if (n == y)
    return;
  // ルーレットを回す
  for (a = 0; a < x; a++) {
    next = n + le[a];
    // ゴール
    if (next >= y) {
      ans += m * dp[m][n] / x;
    } else {
      // イベントマスにとまったか
      flag = 0;
      // for(b=0;b<z;b++){
      if (invE[next] > 0) {
        flag = 1;
        // イベントマスに止まった
        if (invE[next] == 1) {
          c = next + invA[next];
          if (c >= y)
            c = y;
          dp[m][c] += dp[m][n] / x;
          life(m, c);
        }
        if (invE[next] == 2) {
          gm = m + invA[next];
          dp[gm][next] += dp[m][n] / x;
          life(gm, next);
        }
        if (invE[next] == 3) {
          gm = m - invA[next];
          if (gm < 0)
            gm = 0;
          dp[gm][next] += dp[m][n] / x;
          life(gm, next);
        }
      }
      //}
      // イベントマスに止まらなかった
      if (flag == 0) {
        dp[m][next] += dp[m][n] / x;
        life(m, next);
      }
    }
  }
}

int main(void) {
  int a, b;
  while (1) {
    dp[0][0] = 1;
    ans = 0.0;
    cin >> x >> y >> z;
    if (x == 0)
      break;
    for (b = 0; b <= y * 100; b++)
      for (a = 0; a <= y; a++)
        dp[b][a] = 0.0;
    for (a = 0; a <= y; a++)
      invE[a] = 0, invA[a] = 0;
    for (a = 0; a < x; a++)
      cin >> le[a];
    for (a = 0; a < z; a++)
      cin >> invN >> invE[invN] >> invA[invN];
    life(0, 0);
    cout << (int)ans << endl;
  }
  return 0;
}