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

#include <stdio.h>

int H, W, dp[2][10946][2][2], bits[10946], conv[1 << 19], maxbits;

char M[20][21];

int main() {
  scanf("%d", &H);
  scanf("%d", &W);

  for (int i = 0; i < H; i++)
    scanf("%s", M[i]);

  if (M[0][0] == 'J' || M[0][0] == '?')
    dp[0][0][0][0] += 1;
  if (M[0][0] == 'O' || M[0][0] == '?')
    dp[0][0][1][0] += 1;
  if (M[0][0] == 'I' || M[0][0] == '?')
    dp[0][0][1][0] += 1;

  int maxbit = 1 << (W - 1);

  for (int i = 0; i < maxbit; i++) {
    bool ok = true;

    for (int j = 0; j < W - 2; j++) {
      if ((i & (1 << j)) && (i & (1 << (j + 1)))) {
        ok = false;
        break;
      }
    }

    if (ok) {
      conv[i] = maxbits;
      bits[maxbits++] = i;
    }
  }

  for (int i = 0; i < H * W - 1; i++) {
    int s = i % 2;
    int t = (i + 1) % 2;

    for (int j = 0; j < maxbits; j++) {
      dp[t][j][0][0] = 0;
      dp[t][j][0][1] = 0;
      dp[t][j][1][0] = 0;
      dp[t][j][1][1] = 0;
    }

    char nowc = M[i / W][i % W];
    char nxtc = M[(i + 1) / W][(i + 1) % W];

    for (int j = 0; j < maxbits; j++) {
      int nxt = (bits[j] << 1) & (maxbit - 1);

      int sum0 = dp[s][j][0][0] + dp[s][j][1][0];
      int sum1 = dp[s][j][0][1] + dp[s][j][1][1];

      if (nxtc == 'J' || nxtc == '?') {
        dp[t][conv[nxt]][0][0] += sum0;
        dp[t][conv[nxt]][0][1] += sum1;
      }

      if (nxtc == 'O' || nxtc == '?') {
        if ((nowc == 'J' || nowc == '?') && i % W != W - 1) {
          dp[t][conv[nxt + 1]][1][0] += dp[s][j][0][0];
          dp[t][conv[nxt + 1]][1][1] += dp[s][j][0][1];

          dp[t][conv[nxt + 1]][1][0] %= 100000;
          dp[t][conv[nxt + 1]][1][1] %= 100000;

          dp[t][conv[nxt]][1][0] += dp[s][j][1][0];
          dp[t][conv[nxt]][1][1] += dp[s][j][1][1];
        } else {
          dp[t][conv[nxt]][1][0] += sum0;
          dp[t][conv[nxt]][1][1] += sum1;
        }
      }

      if (nxtc == 'I' || nxtc == '?') {
        if (bits[j] & (1 << (W - 2))) {
          dp[t][conv[nxt]][1][1] += sum0;
        } else {
          dp[t][conv[nxt]][1][0] += sum0;
        }

        dp[t][conv[nxt]][1][1] += sum1;
      }

      dp[t][conv[nxt]][0][0] %= 100000;
      dp[t][conv[nxt]][0][1] %= 100000;
      dp[t][conv[nxt]][1][0] %= 100000;
      dp[t][conv[nxt]][1][1] %= 100000;
    }
  }

  int ret = 0;

  int last = (H * W + 1) % 2;

  for (int i = 0; i < maxbits; i++) {
    ret += dp[last][i][0][1];
    ret += dp[last][i][1][1];

    ret %= 100000;
  }

  printf("%d\\n", ret);

  return 0;
}

Error: TLE

Fixed submission:

#include <stdio.h>

int H, W, dp[2][10946][2][2], bits[10946], conv[1 << 19], maxbits;

char M[20][21];

int main() {
  scanf("%d", &H);
  scanf("%d", &W);

  for (int i = 0; i < H; i++)
    scanf("%s", M[i]);

  if (M[0][0] == 'J' || M[0][0] == '?')
    dp[0][0][0][0] += 1;
  if (M[0][0] == 'O' || M[0][0] == '?')
    dp[0][0][1][0] += 1;
  if (M[0][0] == 'I' || M[0][0] == '?')
    dp[0][0][1][0] += 1;

  int maxbit = 1 << (W - 1);

  for (int i = 0; i < maxbit; i++) {
    bool ok = true;

    for (int j = 0; j < W - 2;) {
      if ((i & (1 << j)) && (i & (1 << ++j))) {
        ok = false;
        break;
      }
    }

    if (ok) {
      conv[i] = maxbits;
      bits[maxbits++] = i;
    }
  }

  for (int i = 0; i < H * W - 1; i++) {
    int s = i % 2;
    int t = (i + 1) % 2;

    for (int j = 0; j < maxbits; j++) {
      dp[t][j][0][0] = 0;
      dp[t][j][0][1] = 0;
      dp[t][j][1][0] = 0;
      dp[t][j][1][1] = 0;
    }

    char nowc = M[i / W][i % W];
    char nxtc = M[(i + 1) / W][(i + 1) % W];

    for (int j = 0; j < maxbits; j++) {
      int nxt = (bits[j] << 1) & (maxbit - 1);

      int sum0 = (dp[s][j][0][0] + dp[s][j][1][0]) % 100000;
      int sum1 = (dp[s][j][0][1] + dp[s][j][1][1]) % 100000;

      if (nxtc == 'J' || nxtc == '?') {
        dp[t][conv[nxt]][0][0] += sum0;
        dp[t][conv[nxt]][0][1] += sum1;
      }

      if (nxtc == 'O' || nxtc == '?') {
        if ((nowc == 'J' || nowc == '?') && i % W != W - 1) {
          dp[t][conv[nxt + 1]][1][0] += dp[s][j][0][0];
          dp[t][conv[nxt + 1]][1][1] += dp[s][j][0][1];

          dp[t][conv[nxt + 1]][1][0] %= 100000;
          dp[t][conv[nxt + 1]][1][1] %= 100000;

          dp[t][conv[nxt]][1][0] += dp[s][j][1][0];
          dp[t][conv[nxt]][1][1] += dp[s][j][1][1];
        } else {
          dp[t][conv[nxt]][1][0] += sum0;
          dp[t][conv[nxt]][1][1] += sum1;
        }
      }

      if (nxtc == 'I' || nxtc == '?') {
        if (bits[j] & (1 << (W - 2))) {
          dp[t][conv[nxt]][1][1] += sum0;
        } else {
          dp[t][conv[nxt]][1][0] += sum0;
        }

        dp[t][conv[nxt]][1][1] += sum1;
      }

      dp[t][conv[nxt]][1][0] %= 100000;
      dp[t][conv[nxt]][1][1] %= 100000;
    }
  }

  int ret = 0;

  int last = (H * W + 1) % 2;

  for (int i = 0; i < maxbits; i++) {
    ret += dp[last][i][0][1];
    ret += dp[last][i][1][1];

    ret %= 100000;
  }

  printf("%d\\n", ret);

  return 0;
}