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

#define _USE_MATH_DEFINES
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const int MAX_STATE = 1 << 19, MOD = 1e5;
int H, W, dp[2][3][MAX_STATE][2] = {};

int main() {
  char fld[21][21];
  fill_n((char *)fld, 21 * 21, -1);
  cin >> H >> W;
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++) {
      cin >> fld[i][j];
      if (fld[i][j] == 'J')
        fld[i][j] = 0;
      else if (fld[i][j] == 'O')
        fld[i][j] = 1;
      else if (fld[i][j] == 'I')
        fld[i][j] = 2;
      else
        fld[i][j] = 3;
    }
  fld[H][0] = 0;
  if (fld[0][0] == 3)
    for (int i = 0; i < 3; i++)
      dp[0][i][0][0] = 1;
  else
    dp[0][(int)fld[0][0]][0][0] = 1;

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      for (int joi = 0; joi < 3; joi++) {
        for (int s = 0; s < (1 << (W - 1)); s++) {
          for (int flg = 0; flg < 2; flg++) {
            int dp_c = dp[(i * W + j) & 1][joi][s][flg];
            if (dp_c == 0)
              continue;
            dp[(i * W + j) & 1][joi][s][flg] = 0;
            for (int njoi = 0; njoi < 3; njoi++) {
              if (fld[i + (j + 1) / W][(j + 1) % W] != 3 &&
                  fld[i + (j + 1) / W][(j + 1) % W] != njoi)
                continue;
              int nflg = flg, ns = s;
              if ((j + 1) % W < W - 1 && ((ns >> ((j + 1) % W)) & 1) == 1) {
                if (njoi == 2)
                  nflg = 1;
                ns = ns ^ (1 << ((j + 1) % W));
              }
              if (i < H - 1 && j < W - 1 && joi == 0 && njoi == 1 &&
                  fld[i + 1][j] >= 2) {
                ns = ns | (1 << j);
              }
              dp[(i * W + j + 1) & 1][njoi][ns][nflg] += dp_c % MOD;
            }
          }
        }
      }
    }
  }
  printf("%d\\n", dp[(H * W) & 1][0][0][1] % MOD);
  return 0;
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const int MAX_STATE = 1 << 19, MOD = 1e5;
int H, W, dp[2][3][MAX_STATE][2] = {};

void printBit(int b, int n) {
  for (int i = 0; i < W - 1; i++) {
    if (i == n)
      printf("[%d]", (b >> i) & 1);
    else
      printf("%d", (b >> i) & 1);
  }
  printf(" : %d\\n", b);
}

int main() {
  char fld[21][21];
  fill_n((char *)fld, 21 * 21, -1);
  cin >> H >> W;
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++) {
      cin >> fld[i][j];
      if (fld[i][j] == 'J')
        fld[i][j] = 0;
      else if (fld[i][j] == 'O')
        fld[i][j] = 1;
      else if (fld[i][j] == 'I')
        fld[i][j] = 2;
      else
        fld[i][j] = 3;
    }
  fld[H][0] = 0;
  if (fld[0][0] == 3)
    for (int i = 0; i < 3; i++)
      dp[0][i][0][0] = 1;
  else
    dp[0][(int)fld[0][0]][0][0] = 1;

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      for (int joi = 0; joi < 3; joi++) {
        for (int s = 0; s < (1 << (W - 1)); s++) {
          for (int flg = 0; flg < 2; flg++) {
            int dp_c = dp[(i * W + j) & 1][joi][s][flg];
            dp[(i * W + j) & 1][joi][s][flg] = 0;
            for (int njoi = 0; njoi < 3; njoi++) {
              if (fld[i + (j + 1) / W][(j + 1) % W] != 3 &&
                  fld[i + (j + 1) / W][(j + 1) % W] != njoi)
                continue;
              int nflg = flg, ns = s;
              if ((j + 1) % W < W - 1 && ((ns >> ((j + 1) % W)) & 1) == 1) {
                if (njoi == 2)
                  nflg = 1;
                ns = ns ^ (1 << ((j + 1) % W));
              }
              if (i < H - 1 && j < W - 1 && joi == 0 && njoi == 1 &&
                  fld[i + 1][j] >= 2) {
                ns = ns | (1 << j);
              }
              dp[(i * W + j + 1) & 1][njoi][ns][nflg] += dp_c % MOD;
            }
          }
        }
      }
    }
  }
  printf("%d\\n", dp[(H * W) & 1][0][0][1] % MOD);
  return 0;
}