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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define ALL(co) co.begin(), co.end()
#define tpl(...) make_tuple(__VA_ARGS__)

typedef long long LL;
typedef pair<int, int> P;
typedef pair<int, P> IP;
typedef pair<P, P> PP;
typedef vector<int> Array;
typedef vector<vector<int>> Array2;
typedef vector<LL> LArray;
typedef vector<P> PArray;
typedef vector<string> SArray;

const int INF = 1 << 29;
const LL LINF = 1LL << 60;

inline int getInt() {
  int itiv;
  return (cin >> itiv, itiv);
}
template <typename T> void readAll(vector<T> &vec) {
  for (int i = 0, size = vec.size(); i < size; i++)
    cin >> vec[i];
}
template <typename T, typename U> void readAll(vector<pair<T, U>> &vec) {
  for (int i = 0, size = vec.size(); i < size; i++)
    cin >> vec[i].first >> vec[i].second;
}
template <typename T> inline string toString(const T &a) {
  ostringstream oss;
  oss << a;
  return oss.str();
};
inline bool between(int min, int max, int n) { return min <= n && n <= max; }
inline bool inRange(int begin, int end, int n) { return begin <= n && n < end; }
inline bool inRange(int size, int n) { return 0 <= n && n < size; }

int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
int dr[] = {0, -1, 0, 1}, dc[] = {-1, 0, 1, 0};

// turn, mass, money -> e;
double dp[51][5010];
int x, y, z;

int main(void) {
  while (cin >> x >> y >> z && x) {
    memset(dp, 0, sizeof(dp));
    vector<P> events(y + 1);
    vector<int> roulette(x);
    readAll(roulette);

    int maxmoney = 0;
    for (int i = 0; i < z; i++) {
      int n, e, a;
      cin >> n >> e >> a;
      events[n] = P(e, a);
      if (e == 2)
        maxmoney += a;
    }

    dp[0][0] = 1.;

    double mag = 1.0 / (double)x;

    for (int i = 0; i <= y; i++) {
      for (int j = i; j < y; j++) {
        for (int k = 0; k <= maxmoney; k++) {
          double exp = dp[j][k] * mag;
          for (int l = 0; l < x; l++) {
            int next = min(j + roulette[l], y);
            int money = k;
            int ev = events[next].first;
            int value = events[next].second;
            if (ev != 0) {
              if (ev == 1) {
                next = min(next + value, y);
              }
              if (ev == 2) {
                money += value;
              }
              if (ev == 3) {
                money = max(0, money - value);
              }
            }
            dp[next][money] += exp;
            dp[j][k] = 0;
          }
        }
      }
    }

    double result = 0;
    for (int k = 0; k <= 5000; k++) {
      result += dp[y][k] * k;
    }

    cout << (int)result << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define ALL(co) co.begin(), co.end()
#define tpl(...) make_tuple(__VA_ARGS__)

typedef long long LL;
typedef pair<int, int> P;
typedef pair<int, P> IP;
typedef pair<P, P> PP;
typedef vector<int> Array;
typedef vector<vector<int>> Array2;
typedef vector<LL> LArray;
typedef vector<P> PArray;
typedef vector<string> SArray;

const int INF = 1 << 29;
const LL LINF = 1LL << 60;

inline int getInt() {
  int itiv;
  return (cin >> itiv, itiv);
}
template <typename T> void readAll(vector<T> &vec) {
  for (int i = 0, size = vec.size(); i < size; i++)
    cin >> vec[i];
}
template <typename T, typename U> void readAll(vector<pair<T, U>> &vec) {
  for (int i = 0, size = vec.size(); i < size; i++)
    cin >> vec[i].first >> vec[i].second;
}
template <typename T> inline string toString(const T &a) {
  ostringstream oss;
  oss << a;
  return oss.str();
};
inline bool between(int min, int max, int n) { return min <= n && n <= max; }
inline bool inRange(int begin, int end, int n) { return begin <= n && n < end; }
inline bool inRange(int size, int n) { return 0 <= n && n < size; }

int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
int dr[] = {0, -1, 0, 1}, dc[] = {-1, 0, 1, 0};

// turn, mass, money -> e;
double dp[51][5010];
int x, y, z;

int main(void) {
  while (cin >> x >> y >> z && x) {
    memset(dp, 0, sizeof(dp));
    vector<P> events(y + 1);
    vector<int> roulette(x);
    readAll(roulette);

    for (int i = 0; i < z; i++) {
      int n, e, a;
      cin >> n >> e >> a;
      events[n] = P(e, a);
    }

    dp[0][0] = 1.;

    double mag = 1.0 / (double)x;

    for (int i = 0; i <= y; i++) {
      for (int j = i; j < y; j++) {
        for (int k = 0; k <= 5000; k++) {
          double exp = dp[j][k] * mag;
          for (int l = 0; l < x; l++) {
            int next = min(j + roulette[l], y);
            int money = k;
            int ev = events[next].first;
            int value = events[next].second;
            if (ev != 0) {
              if (ev == 1) {
                next = min(next + value, y);
              }
              if (ev == 2) {
                money += value;
              }
              if (ev == 3) {
                money = max(0, money - value);
              }
            }
            dp[next][money] += exp;
            dp[j][k] = 0;
          }
        }
      }
    }

    double result = 0;
    for (int k = 0; k <= 5000; k++) {
      result += dp[y][k] * k;
    }

    cout << (int)result << endl;
  }
  return 0;
}