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

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

ld dp[555][111][111];
int h, n, p, m, k;
vi hr, sum;

ld solve(int hei, int bar, int use) {
  assert(!(bar < 0 || bar >= n || use < 0));
  if (hei == h) {

    assert(use == 0);
    if (bar == p)
      return 1.0;
    else
      return 0.0;
  }
  if (dp[hei][bar][use] >= 0) {
    return dp[hei][bar][use];
  }
  ld res = 0;
  if (hr[hei] != -1) {
    if (hr[hei] == bar)
      res = solve(hei + 1, bar + 1, use);
    else if (hr[hei] == bar - 1)
      res = solve(hei + 1, bar - 1, use);
    else
      res = solve(hei + 1, bar, use);
  } else {
    ld useexp = use / (ld)(h - hei - (m - sum[hei]));
    if (use > 0) {
      if (bar == 0) {
        res += useexp * (1.0 / (n - 1)) * solve(hei + 1, bar + 1, use - 1);
        res += useexp * (1.0 - 1.0 / (n - 1)) * solve(hei + 1, bar, use - 1);
      } else if (bar == n - 1) {
        res += useexp * (1.0 / (n - 1)) * solve(hei + 1, bar - 1, use - 1);
        res += useexp * (1.0 - 1.0 / (n - 1)) * solve(hei + 1, bar, use - 1);
      } else {
        res += useexp * (1.0 / (n - 1)) * solve(hei + 1, bar + 1, use - 1);
        res += useexp * (1.0 / (n - 1)) * solve(hei + 1, bar - 1, use - 1);
        res += useexp * (1.0 - 2.0 / (n - 1)) * solve(hei + 1, bar, use - 1);
      }
      if (useexp < 1)
        res += (1.0 - useexp) * solve(hei + 1, bar, use);
    } else {
      res += solve(hei + 1, bar, use);
    }
  }
  dp[hei][bar][use] = res;
  return res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  REP(i, 555) REP(j, 111) REP(k, 111) dp[i][j][k] = -1;
  cin >> h >> n >> p >> m >> k;
  p--;
  hr.resize(h, -1);
  sum.resize(h + 1);
  REP(i, m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    hr[a] = b;
    sum[a]++;
  }
  REP(i, h) sum[i + 1] += sum[i];
  ld ans = 0;
  REP(i, n) { chmax(ans, solve(0, i, k)); }
  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

ld dp[555][111][111];
int h, n, p, m, k;
vi hr, sum;

ld solve(int hei, int bar, int use) {
  if (hei == h) {
    if (bar == p)
      return 1.0;
    else
      return 0.0;
  }
  if (dp[hei][bar][use] >= 0) {
    return dp[hei][bar][use];
  }
  ld res = 0;
  if (hr[hei] != -1) {
    if (hr[hei] == bar)
      res = solve(hei + 1, bar + 1, use);
    else if (hr[hei] == bar - 1)
      res = solve(hei + 1, bar - 1, use);
    else
      res = solve(hei + 1, bar, use);
  } else {
    ld useexp = use / (ld)(h - hei - (m - sum[hei]));
    if (use > 0) {
      if (bar == 0) {
        res += useexp * (1.0 / (n - 1.0)) * solve(hei + 1, bar + 1, use - 1);
        res += useexp * (1.0 - 1.0 / (n - 1.0)) * solve(hei + 1, bar, use - 1);
      } else if (bar == n - 1) {
        res += useexp * (1.0 / (n - 1.0)) * solve(hei + 1, bar - 1, use - 1);
        res += useexp * (1.0 - 1.0 / (n - 1.0)) * solve(hei + 1, bar, use - 1);
      } else {
        res += useexp * (1.0 / (n - 1.0)) * solve(hei + 1, bar + 1, use - 1);
        res += useexp * (1.0 / (n - 1.0)) * solve(hei + 1, bar - 1, use - 1);
        res += useexp * (1.0 - 2 / (n - 1.0)) * solve(hei + 1, bar, use - 1);
      }
      res += (1.0 - useexp) * solve(hei + 1, bar, use);
    } else {
      res += solve(hei + 1, bar, use);
    }
  }
  return dp[hei][bar][use] = res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  REP(i, 555) REP(j, 111) REP(k, 111) dp[i][j][k] = -1;
  cin >> h >> n >> p >> m >> k;
  p--;
  hr.resize(h, -1);
  sum.resize(h + 1);
  REP(i, m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    hr[a] = b;
    sum[a]++;
  }
  REP(i, h) sum[i + 1] += sum[i];
  ld ans = 0;
  REP(i, n) { chmax(ans, solve(0, i, k)); }
  cout << ans << endl;
  return 0;
}