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

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for (int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second
#define MP make_pair
#define umap unordered_map

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> P;
typedef unsigned int uint;

// map<tuple<int, int, int, int, int>, double> dp;
// int table[4][4];
// int v[101];
//
// double EPS = 1e-9;
//
// int L, A, B;
// double rec(int n, int acc, int prv, int comb, int pnt){
//	if (n == L) return pnt == 100;
//
//	auto t = make_tuple(n, acc, prv, comb, pnt);
//	if (dp.count(t)) return dp[t];
//	double &res = dp[t];
//
//	res = 0;
//
//	res = rec(n + 1, 0, 4, v[n] ? 0 : comb, pnt);
//	if(v[n] != 0) for (int i = 0; i < 4; ++i){
//		if (v[n] == 2 && i < 2) continue;
//		if (v[n] == 1 && i >= 2) continue;
//		int ip;
//		if (prv == 4) ip = 10;
//		else ip = max(0, (table[prv][i] - 10) + acc);
//		double p = ip / 10.;
//
//		double tmp = 0;
//		if(p > EPS) tmp += p*rec(n + 1, ip, i, comb+1, min(100,
//pnt+A+B*min(comb, 10))); 		if(1-p > EPS) tmp += (1 - p)*rec(n + 1, ip, i, 0,
//pnt); 		res = max(res, tmp);
//	}
//
//	return res;
// }

int table[4][4];
int v[101];

double EPS = 1e-9;
int L, A, B;

double dp[2][11][5][11][101]; // i, prv_acc, prv_pos, combo, point

int main() {
  cout.setf(ios::fixed);
  cout.precision(10);
  while (1) {
    rep(i, 4) rep(j, 4) {
      cin >> table[i][j];
      if (table[i][j] < 0)
        goto end;
    }
    cin >> L;
    rep(i, L) cin >> v[i];
    cin >> A >> B;
    A /= 100, B /= 100;

    int cur = 0, nxt = 1;
    rep(i, 11) rep(j, 5) rep(k, 11) rep(l, 101) dp[cur][i][j][k][l] = l == 100;
    for (int n = L - 1; n >= 0; --n) {
      rep(acc, 11) rep(prv, 5) rep(comb, 11) rep(pnt, 101) {
        double &res = dp[nxt][acc][prv][comb][pnt];
        res = 0;

        res = dp[cur][0][4][v[n] ? 0 : comb][pnt];
        if (v[n] != 0)
          for (int i = 0; i < 4; ++i) {
            if (v[n] == 2 && i < 2)
              continue;
            if (v[n] == 1 && i >= 2)
              continue;
            int ip;
            if (prv == 4)
              ip = 10;
            else
              ip = max(0, (table[prv][i] - 10) + acc);
            double p = ip * .1;

            double tmp = 0;
            tmp += p * dp[cur][ip][i][min(10, comb + 1)]
                         [min(100, pnt + A + B * min(comb, 10))];
            tmp += (1 - p) * dp[cur][ip][i][0][pnt];
            res = max(res, tmp);
          }
      }
      swap(cur, nxt);
    }
    cout << dp[cur][0][4][0][0] << endl;
  }

end:
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for (int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second
#define MP make_pair
#define umap unordered_map

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> P;
typedef unsigned int uint;

// map<tuple<int, int, int, int, int>, double> dp;
// int table[4][4];
// int v[101];
//
// double EPS = 1e-9;
//
// int L, A, B;
// double rec(int n, int acc, int prv, int comb, int pnt){
//	if (n == L) return pnt == 100;
//
//	auto t = make_tuple(n, acc, prv, comb, pnt);
//	if (dp.count(t)) return dp[t];
//	double &res = dp[t];
//
//	res = 0;
//
//	res = rec(n + 1, 0, 4, v[n] ? 0 : comb, pnt);
//	if(v[n] != 0) for (int i = 0; i < 4; ++i){
//		if (v[n] == 2 && i < 2) continue;
//		if (v[n] == 1 && i >= 2) continue;
//		int ip;
//		if (prv == 4) ip = 10;
//		else ip = max(0, (table[prv][i] - 10) + acc);
//		double p = ip / 10.;
//
//		double tmp = 0;
//		if(p > EPS) tmp += p*rec(n + 1, ip, i, comb+1, min(100,
//pnt+A+B*min(comb, 10))); 		if(1-p > EPS) tmp += (1 - p)*rec(n + 1, ip, i, 0,
//pnt); 		res = max(res, tmp);
//	}
//
//	return res;
// }

int table[4][4];
int v[101];

double EPS = 1e-9;
int L, A, B;

double dp[2][11][5][101][101]; // i, prv_acc, prv_pos, combo, point

int main() {
  cout.setf(ios::fixed);
  cout.precision(10);
  while (1) {
    rep(i, 4) rep(j, 4) {
      cin >> table[i][j];
      if (table[i][j] < 0)
        goto end;
    }
    cin >> L;
    rep(i, L) cin >> v[i];
    cin >> A >> B;
    A /= 100, B /= 100;

    int cur = 0, nxt = 1;
    rep(i, 11) rep(j, 5) rep(k, 101) rep(l, 101) dp[cur][i][j][k][l] = l == 100;
    for (int n = L - 1; n >= 0; --n) {
      rep(acc, 11) rep(prv, 5) rep(comb, 101) rep(pnt, 101) {
        double &res = dp[nxt][acc][prv][comb][pnt];
        res = 0;

        res = dp[cur][0][4][v[n] ? 0 : comb][pnt];
        if (v[n] != 0)
          for (int i = 0; i < 4; ++i) {
            if (v[n] == 2 && i < 2)
              continue;
            if (v[n] == 1 && i >= 2)
              continue;
            int ip;
            if (prv == 4)
              ip = 10;
            else
              ip = max(0, (table[prv][i] - 10) + acc);
            double p = ip * .1;

            double tmp = 0;
            tmp +=
                p *
                dp[cur][ip][i][comb + 1][min(100, pnt + A + B * min(comb, 10))];
            tmp += (1 - p) * dp[cur][ip][i][0][pnt];
            res = max(res, tmp);
          }
      }
      swap(cur, nxt);
    }
    cout << dp[cur][0][4][0][0] << endl;
  }

end:
  return 0;
}