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

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;
const int MAXA = 100;
const int MAXP = 10000;
int L;
// bool used[105][5][11][101][11];
double memo[101][5][11][101][11];
double get(int idx, int last, int ac, int point, int cmb) {
  if (point >= 100)
    point = 100;
  if (cmb >= 11)
    cmb = 10;
  if (idx == L)
    return (point == 100 ? 1.0 : 0.0);
  // assert(point % 100 == 0);
  // point /= 100;
  // assert(ac % 10 == 0);
  // ac /= 10;
  // assert(idx >= 0 && idx < 101);
  // assert(last >= 0 && last < 5);
  // assert(ac >= 0 && ac < 11);
  // assert(point >= 0 && point < 101);
  // assert(cmb >= 0 && cmb < 11);
  // assert(used[idx][last][ac][point][cmb]);
  return memo[idx][last][ac][point][cmb];
}

void Set(int idx, int last, int ac, int point, int cmb, double val) {
  // used[idx][last][ac][point][cmb] = true;
  // assert(point % 100 == 0);
  // point /= 100;
  // assert(ac % 10 == 0);
  // ac /= 10;
  //  assert(idx >= 0 && idx < 101);
  //  assert(last >= 0 && last < 5);
  //  assert(ac >= 0 && ac < 11);
  //  assert(point >= 0 && point < 101);
  //  assert(cmb >= 0 && cmb < 11);
  memo[idx][last][ac][point][cmb] = val;
}

int main() {
  while (true) {
    // memset(used, 0, sizeof(used));

    int D[5][5];
    REP(y, 4) REP(x, 4) cin >> D[y][x];
    if (D[0][0] < 0)
      break;

    cin >> L;

    vector<int> s(L);
    REP(i, L) cin >> s[i];

    int A, B;
    cin >> A >> B;
    A /= 100;
    B /= 100;
    double probA[11] = {};
    double probB[11] = {};
    REP(i, 11) probA[i] = i / 10.0;
    REP(i, 11) probB[i] = (10.0 - i) / 10.0;

    for (int i = L - 1; i >= 0; i--) {
      for (int last = 0; last < 5; last++) {
        for (int ac = 0; ac <= 10; ac++) {
          for (int point = 0; point <= 100; point++) {
            for (int cmb = 0; cmb <= 10; cmb++) {
              double res = 0.0;
              if (s[i] == 1)
                for (int act = 0; act < 2; act++) {
                  int nac = 10;
                  if (last != 4) {
                    nac = max(0, (D[last][act] - 10) + ac);
                  }

                  int ncmb = cmb + 1;
                  int npoint = point + A + B * cmb;
                  // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb ==
                  // 0) {
                  //     printf("i = %d last = %d ac = %d point = %d cmb = %d
                  //     act = %d res = %f\\n",
                  //             i+1, act, nac, npoint, ncmb, act, (double)ac /
                  //             100.0 * get(i+1, act, nac, npoint, ncmb)
                  //             );
                  // }
                  double cand =
                      probA[nac] * get(i + 1, act, nac, npoint, ncmb) +
                      probB[nac] * get(i + 1, act, nac, point, 0);
                  if (res < cand) {
                    res = cand;
                  }
                }
              if (s[i] == 2)
                for (int act = 2; act < 4; act++) {
                  int nac = 10;
                  if (last != 4) {
                    nac = max(0, (D[last][act] - 10) + ac);
                  }

                  int ncmb = cmb + 1;
                  int npoint = point + A + B * cmb;
                  // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb ==
                  // 0) {
                  //     printf("i = %d last = %d ac = %d point = %d cmb = %d
                  //     act = %d res = %f\\n",
                  //             i+1, act, nac, npoint, ncmb, act, (double)ac /
                  //             100.0 * get(i+1, act, nac, npoint, ncmb)
                  //             );
                  // }
                  double cand =
                      probA[nac] * get(i + 1, act, nac, npoint, ncmb) +
                      probB[nac] * get(i + 1, act, nac, point, 0);
                  if (res < cand) {
                    res = cand;
                  }
                }
              {
                int nac = 10;
                int ncmb = (s[i] == 0 ? cmb : 0);
                int npoint = point;
                double cand = get(i + 1, 4, nac, npoint, ncmb);
                if (res < cand) {
                  res = cand;
                }
              }
              // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0)
              // {
              //     printf("i = %d last = %d ac = %d point = %d cmb = %d act =
              //     %d res = %f\\n",
              //             i, last, ac, point, cmb, ACT, res);
              // }
              Set(i, last, ac, point, cmb, res);
            }
          }
        }
      }
    }

    printf("%.12f\\n", get(0, 4, 10, 0, 0));
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;
const int MAXA = 100;
const int MAXP = 10000;
int L;
// bool used[105][5][11][101][11];
double memo[101][5][11][101][11];
double get(int idx, int last, int ac, int point, int cmb) {
  if (point >= 100)
    point = 100;
  if (cmb >= 11)
    cmb = 10;
  if (idx == L)
    return (point == 100 ? 1.0 : 0.0);
  // assert(point % 100 == 0);
  // point /= 100;
  // assert(ac % 10 == 0);
  // ac /= 10;
  // assert(idx >= 0 && idx < 101);
  // assert(last >= 0 && last < 5);
  // assert(ac >= 0 && ac < 11);
  // assert(point >= 0 && point < 101);
  // assert(cmb >= 0 && cmb < 11);
  // assert(used[idx][last][ac][point][cmb]);
  return memo[idx][last][ac][point][cmb];
}

void Set(int idx, int last, int ac, int point, int cmb, double val) {
  // used[idx][last][ac][point][cmb] = true;
  // assert(point % 100 == 0);
  // point /= 100;
  // assert(ac % 10 == 0);
  // ac /= 10;
  //  assert(idx >= 0 && idx < 101);
  //  assert(last >= 0 && last < 5);
  //  assert(ac >= 0 && ac < 11);
  //  assert(point >= 0 && point < 101);
  //  assert(cmb >= 0 && cmb < 11);
  memo[idx][last][ac][point][cmb] = val;
}

int main() {
  while (true) {
    // memset(used, 0, sizeof(used));

    int D[5][5];
    REP(y, 4) REP(x, 4) cin >> D[y][x];
    if (D[0][0] < 0)
      break;

    cin >> L;

    vector<int> s(L);
    REP(i, L) cin >> s[i];

    int A, B;
    cin >> A >> B;
    A /= 100;
    B /= 100;
    for (int i = L - 1; i >= 0; i--) {
      for (int last = 0; last < 5; last++) {
        for (int ac = 0; ac <= 10; ac++) {
          for (int point = 0; point <= 100; point++) {
            for (int cmb = 0; cmb <= 10; cmb++) {
              double res = 0.0;
              for (int act = 0; act < 4; act++) {
                if (s[i] == 0)
                  continue;
                if (s[i] == 1 && act >= 2)
                  continue;
                if (s[i] == 2 && act <= 1)
                  continue;

                int nac = -1;
                if (last == 4) {
                  nac = 10;
                } else {
                  nac = max(0, (D[last][act] - 10) + ac);
                }

                int ncmb = cmb + 1;
                int npoint = point + A + B * cmb;
                // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb ==
                // 0) {
                //     printf("i = %d last = %d ac = %d point = %d cmb = %d act
                //     = %d res = %f\\n",
                //             i+1, act, nac, npoint, ncmb, act, (double)ac /
                //             100.0 * get(i+1, act, nac, npoint, ncmb)
                //             );
                // }
                double cand =
                    (double)nac / 10.0 * get(i + 1, act, nac, npoint, ncmb) +
                    (10.0 - nac) / 10.0 * get(i + 1, act, nac, point, 0);
                if (res < cand) {
                  res = cand;
                }
              }
              {
                int nac = 10;
                int ncmb = (s[i] == 0 ? cmb : 0);
                int npoint = point;
                double cand = get(i + 1, 4, nac, npoint, ncmb);
                if (res < cand) {
                  res = cand;
                }
              }
              // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0)
              // {
              //     printf("i = %d last = %d ac = %d point = %d cmb = %d act =
              //     %d res = %f\\n",
              //             i, last, ac, point, cmb, ACT, res);
              // }
              Set(i, last, ac, point, cmb, res);
            }
          }
        }
      }
    }

    printf("%.12f\\n", get(0, 4, 10, 0, 0));
  }
  return 0;
}