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

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

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;

int main() {
  int H, N, P, M, K;
  while (cin >> H >> N >> P >> M >> K) {
    double ans = 0;
    int stick[501] = {};
    memset(stick, -1, sizeof(stick));
    REP(i, M) {
      int A, B;
      cin >> A >> B;
      B--;
      stick[A] = B;
    }
    int cnt[501] = {};
    for (int h = 1; h <= 500; h++) {
      cnt[h] = cnt[h - 1];
      if (stick[h] != -1)
        cnt[h]++;
    }
    static double dp[501][101][101]; //[h][x][use]
    for (int s = 0; s < N; s++) {
      memset(dp, 0, sizeof(dp));
      dp[0][s][0] = 1;
      // printf("start: %d\\n", s);
      for (int h = 0; h < H; h++) {
        if (stick[h + 1] != -1) {
          for (int x = 0; x < N; x++) {
            int to = x;
            if (x == stick[h + 1] || x == stick[h + 1] + 1) {
              to = (x == stick[h + 1]) ? (x + 1) : (x - 1);
            }
            for (int use = 0; use <= K; use++) {
              dp[h + 1][to][use] += dp[h][x][use];
            }
          }
        } else {
          for (int use = 0; use <= K; use++) {
            const double P_H = (double)(K - use) / (H - (M - cnt[h + 1]) - h);
            const double P_N = 1.0 / (N - 1);
            if (use != K) {
              {
                int x = 0;
                const double P = P_H * P_N;
                const double not_P_N = 1 - P_N;
                dp[h + 1][x + 1][use + 1] += dp[h][x][use] * P;
                dp[h + 1][x][use + 1] += dp[h][x][use] * P_H * not_P_N;
                dp[h + 1][x][use] += dp[h][x][use] * (1 - P_H);
              }
              for (int x = 1; x < N - 1; x++) {
                const double P = P_H * P_N;
                double not_P_N = 1 - 2 * P_N;
                dp[h + 1][x - 1][use + 1] += dp[h][x][use] * P;
                dp[h + 1][x + 1][use + 1] += dp[h][x][use] * P;
                dp[h + 1][x][use + 1] += dp[h][x][use] * P_H * not_P_N;
                dp[h + 1][x][use] += dp[h][x][use] * (1 - P_H);
              }
              {
                int x = N - 1;
                const double P = P_H * P_N;
                const double not_P_N = 1 - P_N;
                dp[h + 1][x - 1][use + 1] += dp[h][x][use] * P;
                dp[h + 1][x][use + 1] += dp[h][x][use] * P_H * not_P_N;
                dp[h + 1][x][use] += dp[h][x][use] * (1 - P_H);
              }
            } else {
              for (int x = 0; x < N; x++)
                dp[h + 1][x][use] += dp[h][x][use] * (1 - P_H);
            }
          }
        }
        /*
        printf("height: %d\\n", h + 1);
        for(int x = 0; x < N; x++){
          for(int use = 0; use <= K; use++){
            printf("  x:%d p:%f use:%d\\n", x, dp[h + 1][x][use], use);
          }
        }
        */
      }
      ans = max(ans, dp[H][P - 1][K]);
    }
    printf("%.9f\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

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

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;

int main() {
  int H, N, P, M, K;
  while (cin >> H >> N >> P >> M >> K) {
    double ans = 0;
    int stick[501] = {};
    memset(stick, -1, sizeof(stick));
    REP(i, M) {
      int A, B;
      cin >> A >> B;
      B--;
      stick[A] = B;
    }
    int cnt[501] = {};
    for (int h = 1; h <= 500; h++) {
      cnt[h] = cnt[h - 1];
      if (stick[h] != -1)
        cnt[h]++;
    }
    static double dp[501][101][101]; //[h][x][use]
    for (int s = 0; s < N; s++) {
      memset(dp, 0, sizeof(dp));
      dp[0][s][0] = 1;
      // printf("start: %d\\n", s);
      for (int h = 0; h < H; h++) {
        if (stick[h + 1] != -1) {
          for (int x = 0; x < N; x++) {
            int to = x;
            if (x == stick[h + 1] || x == stick[h + 1] + 1) {
              to = (x == stick[h + 1]) ? (x + 1) : (x - 1);
            }
            for (int use = 0; use <= K; use++) {
              dp[h + 1][to][use] += dp[h][x][use];
            }
          }
        } else {
          for (int use = 0; use <= K; use++) {
            const double P_H = (double)(K - use) / (H - (M - cnt[h + 1]) - h);
            const double P_N = 1.0 / (N - 1);
            if (use != K) {
              for (int x = 0; x < N; x++) {
                const double P = P_H * P_N;
                double not_P_N = 1;
                if (x != 0) {
                  int to = x - 1;
                  dp[h + 1][to][use + 1] += dp[h][x][use] * P;
                  not_P_N -= P_N;
                }
                if (x != N - 1) {
                  int to = x + 1;
                  dp[h + 1][to][use + 1] += dp[h][x][use] * P;
                  not_P_N -= P_N;
                }
                dp[h + 1][x][use + 1] += dp[h][x][use] * P_H * not_P_N;
                dp[h + 1][x][use] += dp[h][x][use] * (1 - P_H);
              }
            } else {
              for (int x = 0; x < N; x++)
                dp[h + 1][x][use] += dp[h][x][use] * (1 - P_H);
            }
          }
        }
        /*
        printf("height: %d\\n", h + 1);
        for(int x = 0; x < N; x++){
          for(int use = 0; use <= K; use++){
            printf("  x:%d p:%f use:%d\\n", x, dp[h + 1][x][use], use);
          }
        }
        */
      }
      ans = max(ans, dp[H][P - 1][K]);
    }
    printf("%.9f\\n", ans);
  }
  return 0;
}