Problem p00482 (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 int T;
const T MOD = 100000;
inline void add(T &x, T y) {
  x = (x + y);
  while (x >= MOD) {
    x -= MOD;
  }
}

int main() {
  const string JOI = "JOI";
  int H, W;
  while (cin >> H >> W) {
    string flag[20];
    REP(y, H) cin >> flag[y];

    static T dp[1 << 20][2][2] = {}; // JO flag, last is J, satisfy
    REP(s, 1 << W) REP(i, 2) REP(j, 2) dp[s][i][j] = 0;
    dp[0][0][0] = 1;
    for (int y = 0; y < H; y++)
      for (int x = 0; x < W; x++) {
        static T next[1 << 20][2][2] = {};
        REP(s, 1 << W) REP(i, 2) REP(j, 2) next[s][i][j] = 0;

        for (int s = 0; s < (1 << W); s++)
          for (int lastJ = 0; lastJ < 2; lastJ++)
            for (int satis = 0; satis < 2; satis++) {
              if (dp[s][lastJ][satis] == 0)
                continue;
              // printf("x:%d y:%d s:%d lastJ:%d satis:%d dp:%d\\n", x, y, s,
              // lastJ, satis, dp[s][lastJ][satis]);
              for (char c : JOI) {
                if (flag[y][x] != '?' && flag[y][x] != c)
                  continue;
                int ns = s & ~(1 << x);
                if (c == 'J') {
                  // printf("J: next[%d][%d][%d] <- %d\\n", ns, 1, satis,
                  // dp[s][lastJ][satis]);
                  add(next[ns][1][satis], dp[s][lastJ][satis]);
                } else if (c == 'O') {
                  if (x > 0 && lastJ)
                    ns |= (1 << (x - 1));
                  // printf("O: next[%d][%d][%d] <- %d\\n", ns, 0, satis,
                  // dp[s][lastJ][satis]);
                  add(next[ns][0][satis], dp[s][lastJ][satis]);
                } else if (c == 'I') {
                  int nsatis = satis;
                  if (s >> x & 1)
                    nsatis = 1;
                  // printf("I: next[%d][%d][%d] <- %d\\n", ns, 0, nsatis,
                  // dp[s][lastJ][satis]);
                  add(next[ns][0][nsatis], dp[s][lastJ][satis]);
                }
              }
            }

        REP(s, 1 << W)
        REP(lastJ, 2) REP(satis, 2) dp[s][lastJ][satis] = next[s][lastJ][satis];
      }
    T ans = 0;
    for (int s = 0; s < (1 << W); s++)
      for (int lastJ = 0; lastJ < 2; lastJ++) {
        add(ans, dp[s][lastJ][1]);
      }
    cout << ans << endl;
  }
  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 int T;
const T MOD = 100000;
inline void add(T &x, T y) { x = (x + y) % MOD; }

int main() {
  const string JOI = "JOI";
  int H, W;
  while (cin >> H >> W) {
    string flag[20];
    REP(y, H) cin >> flag[y];

    static T dp[1 << 20][2][2] = {}; // JO flag, last is J, satisfy
    memset(dp, 0, sizeof(dp));
    dp[0][0][0] = 1;
    for (int y = 0; y < H; y++)
      for (int x = 0; x < W; x++) {
        static T next[1 << 20][2][2] = {};
        memset(next, 0, sizeof(next));

        for (int s = 0; s < (1 << W); s++)
          for (int lastJ = 0; lastJ < 2; lastJ++)
            for (int satis = 0; satis < 2; satis++) {
              // printf("x:%d y:%d s:%d lastJ:%d satis:%d dp:%d\\n", x, y, s,
              // lastJ, satis, dp[s][lastJ][satis]);
              for (char c : JOI) {
                if (flag[y][x] != '?' && flag[y][x] != c)
                  continue;
                int ns = s & ~(1 << x);
                if (c == 'J') {
                  // printf("J: next[%d][%d][%d] <- %d\\n", ns, 1, satis,
                  // dp[s][lastJ][satis]);
                  add(next[ns][1][satis], dp[s][lastJ][satis]);
                } else if (c == 'O') {
                  if (x > 0 && lastJ)
                    ns |= (1 << (x - 1));
                  // printf("O: next[%d][%d][%d] <- %d\\n", ns, 0, satis,
                  // dp[s][lastJ][satis]);
                  add(next[ns][0][satis], dp[s][lastJ][satis]);
                } else if (c == 'I') {
                  int nsatis = satis;
                  if (s >> x & 1)
                    nsatis = 1;
                  // printf("I: next[%d][%d][%d] <- %d\\n", ns, 0, nsatis,
                  // dp[s][lastJ][satis]);
                  add(next[ns][0][nsatis], dp[s][lastJ][satis]);
                }
              }
            }

        REP(s, 1 << W)
        REP(lastJ, 2) REP(satis, 2) dp[s][lastJ][satis] = next[s][lastJ][satis];
      }
    T ans = 0;
    for (int s = 0; s < (1 << W); s++)
      for (int lastJ = 0; lastJ < 2; lastJ++) {
        add(ans, dp[s][lastJ][1]);
      }
    cout << ans << endl;
  }
  return 0;
}