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

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

#define MOD 100000
int M, N;
char S[20][20];
int idx[1 << 20];
int idx_r[1 << 20];
int dp[2][20000][3];
int bf[20][20];

int f(char c) {
  if (c == 'J')
    return 0;
  if (c == 'O')
    return 1;
  if (c == 'I')
    return 2;
  exit(1);
}

int main() {
  cin >> M >> N;
  for (int i = 0; i < M; i++) {
    for (int j = 0; j < N; j++) {
      cin >> S[i][j];
    }
  }

  int ctr = 0;
  for (int i = 0; i < (1 << N); i++) {
    bool f = true;
    for (int j = 1; j < N; j++) {
      if ((i & (1 << (j - 1))) != 0 && (i & (1 << j)) != 0) {
        f = false;
        break;
      }
    }
    if (!f)
      continue;
    idx[i] = ctr;
    idx_r[ctr] = i;
    ctr += 1;
  }

  for (int k = 0; k < 3; k++) {
    if (S[0][0] != '?' && f(S[0][0]) != k)
      continue;
    dp[0][0][k] = 1;
  }

  for (int y = 0; y < M; y++) {
    for (int x = 0; x < N; x++) {
      int p = y * N + x;
      if (p == 0)
        continue;
      for (int s = 0; s < ctr; s++) {
        for (int k = 0; k < 3; k++) {
          for (int g = 0; g < 3; g++) {
            if (S[y][x] != '?' && f(S[y][x]) != g)
              continue;

            int ns = idx_r[s] >> 1;
            if (x != 0 && k == 0 && g == 1)
              ns |= 1 << (N - 1);

            if (x != N - 1 && (ns & 1) != 0 && g == 2) {
              bf[y][x] += dp[(p - 1) % 2][s][k];
              bf[y][x] %= MOD;
              continue;
            }
            dp[p % 2][idx[ns]][g] += dp[(p - 1) % 2][s][k];
            dp[p % 2][idx[ns]][g] %= MOD;
          }
        }
      }
      for (int s = 0; s < ctr; s++) {
        for (int k = 0; k < 3; k++) {
          dp[(p - 1) % 2][s][k] = 0;
        }
      }
    }
  }

  long long ans = 0;
  long long t = 1;
  for (int y = M - 1; y >= 0; y--) {
    for (int x = N - 1; x >= 0; x--) {
      ans = (ans + (t * (long long)bf[y][x] % MOD)) % MOD;
      if (S[y][x] == '?')
        t = (t * 3) % MOD;
    }
  }

  cout << ans << "\\n";
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

#define MOD 100000
int M, N;
char S[20][20];
int dp[2][1 << 20][3];
int bf[20][20];
char T[3] = {'J', 'O', 'I'};

int f(char c) {
  if (c == 'J')
    return 0;
  if (c == 'O')
    return 1;
  if (c == 'I')
    return 2;
  exit(1);
}

int main() {
  cin >> M >> N;
  for (int i = 0; i < M; i++) {
    for (int j = 0; j < N; j++) {
      cin >> S[i][j];
    }
  }

  for (int k = 0; k < 3; k++) {
    if (S[0][0] != '?' && f(S[0][0]) != k)
      continue;
    dp[0][0][k] = 1;
  }

  for (int y = 0; y < M; y++) {
    for (int x = 0; x < N; x++) {
      int p = y * N + x;
      if (p == 0)
        continue;
      for (int s = 0; s < (1 << N); s++) {
        for (int k = 0; k < 3; k++) {
          for (int g = 0; g < 3; g++) {
            if (S[y][x] != '?' && f(S[y][x]) != g)
              continue;

            int ns = s >> 1;
            if (x != 0 && k == 0 && g == 1)
              ns |= 1 << (N - 1);

            if (x != N - 1 && (ns & 1) != 0 && g == 2) {
              bf[y][x] += dp[(p - 1) % 2][s][k];
              bf[y][x] %= MOD;
              continue;
            }
            dp[p % 2][ns][g] += dp[(p - 1) % 2][s][k];
            dp[p % 2][ns][g] %= MOD;
          }
        }
      }
      for (int s = 0; s < (1 << N); s++) {
        for (int k = 0; k < 3; k++) {
          dp[(p - 1) % 2][s][k] = 0;
        }
      }
    }
  }

  long long ans = 0;
  long long t = 1;
  for (int y = M - 1; y >= 0; y--) {
    for (int x = N - 1; x >= 0; x--) {
      ans = (ans + (t * (long long)bf[y][x] % MOD)) % MOD;
      if (S[y][x] == '?')
        t = (t * 3) % MOD;
    }
  }

  cout << ans << "\\n";
  return 0;
}