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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

typedef long double real;
#define EQ(x, y) (abs((x) - (y)) < EPS)

real EPS = 1e-9;

const int MAX_N = 101;
const int MAX_M = 53;

const bool debug = false;

int N, M;
real L;
vector<real> P, T, V;
void input() {
  cin >> N >> M >> L;
  P.clear();
  P.resize(N);
  T.clear();
  T.resize(N);
  V.clear();
  V.resize(N);
  for (int i = 0; i < N; i++) {
    cin >> P[i] >> T[i] >> V[i];
    P[i] /= 100;
  }
}

real X[MAX_N][MAX_M]; // X[i][j] :: i人目がm回休む確率
real S[MAX_N][MAX_M]; // S[i][j] :: i人目がm回未満だけ休む確率

void init() {
  for (int i = 0; i < N; i++)
    for (int j = 0; j <= M; j++)
      X[i][j] = 0;
  for (int i = 0; i < N; i++)
    for (int j = 0; j <= M + 1; j++)
      S[i][j] = 0;
  for (int i = 0; i < N; i++) {
    static real dp[MAX_M][MAX_M];
    for (int j = 0; j <= M; j++)
      for (int k = 0; k <= M; k++)
        dp[j][k] = 0;
    dp[0][0] = 1;
    for (int j = 0; j < M; j++) {
      for (int k = 0; k <= j; k++) {
        dp[j + 1][k] += dp[j][k] * (1.0 - P[i]);
        dp[j + 1][k + 1] += dp[j][k] * P[i];
      }
    }
    for (int k = 0; k <= M; k++) {
      X[i][k] = dp[M][k];
    }
  }
  for (int i = 0; i < N; i++) {
    S[i][0] = 0;
    for (int j = 0; j <= M; j++) {
      S[i][j + 1] = S[i][j] + X[i][j];
    }
  }
}

void solve() {
  init();
  for (int i = 0; i < N; i++) { // i人目
    if (V[i] == 0) {
      printf("%.12Lf\\n", real(0));
      continue;
    }
    real ans = 0;
    for (int j = 0; j <= M; j++) { // j回休んだ
      real p = X[i][j];
      real time = L / V[i] + j * T[i];
      for (int k = 0; k < N; k++) { // k人目
        if (i == k)
          continue;
        if (EQ(T[k], 0)) {
          p *= (L / V[k] - EPS > time);
        } else {
          // c回以上休む必要
          int c = max(0, int(ceil((time - L / V[k]) / T[k] + EPS) + EPS));
          if (c > M) {
            p = 0;
            break;
          }
          real pk = 1.0 - S[k][c];
          p *= pk;
        }
      }
      ans += p;
    }
    printf("%.12Lf\\n", ans);
  }
}

int main() {
  input();
  solve();
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

typedef long double real;
#define EQ(x, y) (abs((x) - (y)) < EPS)

real EPS = 1e-9;

const int MAX_N = 101;
const int MAX_M = 53;

const bool debug = false;

int N, M, L;
vector<real> P, T, V;
void input() {
  cin >> N >> M >> L;
  P.clear();
  P.resize(N);
  T.clear();
  T.resize(N);
  V.clear();
  V.resize(N);
  for (int i = 0; i < N; i++) {
    cin >> P[i] >> T[i] >> V[i];
    P[i] /= 100;
  }
}

real X[MAX_N][MAX_M]; // X[i][j] :: i人目がm回休む確率
real S[MAX_N][MAX_M]; // S[i][j] :: i人目がm回未満だけ休む確率

void init() {
  for (int i = 0; i < N; i++)
    for (int j = 0; j <= M; j++)
      X[i][j] = 0;
  for (int i = 0; i < N; i++)
    for (int j = 0; j <= M + 1; j++)
      S[i][j] = 0;
  for (int i = 0; i < N; i++) {
    static real dp[MAX_M][MAX_M];
    for (int j = 0; j <= M; j++)
      for (int k = 0; k <= M; k++)
        dp[j][k] = 0;
    dp[0][0] = 1;
    for (int j = 0; j < M; j++) {
      for (int k = 0; k <= j; k++) {
        dp[j + 1][k] += dp[j][k] * (1.0 - P[i]);
        dp[j + 1][k + 1] += dp[j][k] * P[i];
      }
    }
    for (int k = 0; k <= M; k++) {
      X[i][k] = dp[M][k];
    }
  }
  for (int i = 0; i < N; i++) {
    S[i][0] = 0;
    for (int j = 0; j <= M; j++) {
      S[i][j + 1] = S[i][j] + X[i][j];
    }
  }
  if (debug) {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j <= M; j++) {
        printf("%3.3Lf ", X[i][j]);
      }
      cout << endl;
    }
  }
}

void solve() {
  init();
  for (int i = 0; i < N; i++) { // i人目
    if (V[i] == 0) {
      printf("%.12Lf\\n", real(N == 1 ? 1 : 0));
      continue;
    }
    real ans = 0;
    for (int j = 0; j <= M; j++) { // j回休んだ
      real p = X[i][j];
      real time = L / V[i] + j * T[i];
      for (int k = 0; k < N; k++) { // k人目
        if (i == k)
          continue;
        if (T[k] == 0) {
          p *= (L / V[k] - EPS > time);
          continue;
        }
        // c回以上休む必要
        int c = int(ceil((time - L / V[k]) / T[k] + EPS) + EPS);
        if (c > M) {
          p = 0;
          break;
        }
        real pk = 1.0 - S[k][c];
        p *= pk;
      }
      ans += p;
    }
    printf("%.12Lf\\n", ans);
  }
}

int main() {
  input();
  solve();
  return 0;
}