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

#include <iostream>
#include <string.h>
#include <string>
#include <vector>
using namespace std;

int w, h;
const int MOD = 100000;

int dp[2][1 << 20];

void solve() {
  int res = 1;
  vector<string> V;
  for (int i = 0; i < h; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < s.size(); j++) {
      if (s[j] == '?')
        res *= 3;
      res %= MOD;
    }
    V.push_back(s);
  }

  if (w == 1 || h == 1) {
    cout << res << endl;
    return;
  }

  for (int y = 1; y < h; y++) {
    for (int x = 0; x < w - 1; x++) {
      if (V[y][x] == 'I' && V[y - 1][x] == 'J' && V[y - 1][x + 1] == 'O') {
        cout << res << endl;
        return;
      }
    }
  }

  if (res == 1) {
    cout << 0 << endl;
    return;
  }

  memset(dp, 0, sizeof(dp));

  int *before = dp[0];
  int *now = dp[1];

  // ÅãÌbitÍJÅ é©Ç¤©
  // »êÈOÍA©ªªJÅ©ÂEªOÅ é©

  memset(before, 0, sizeof(before));
  before[0] = 1;

  for (int y = 0; y < h; y++) {
    memset(now, 0, sizeof(now));
    for (int x = 0; x < w; x++) {

      for (int bit = 0; bit < 1 << w; bit++) {
        int nbit;
        nbit = bit & (~1);
        nbit = nbit << 1;
        nbit = nbit & (~(1 << w));
        if (before[bit] == 0)
          continue;

        if (x == 0) {
          if (bit & (1 << (w - 1))) {
            if (V[y][x] == 'O' || V[y][x] == '?')
              now[nbit] += before[bit]; // O;
            if (V[y][x] == 'J' || V[y][x] == '?')
              now[nbit | 1] += before[bit]; // J
          } else {
            if (V[y][x] == 'O' || V[y][x] == '?')
              now[nbit] += before[bit]; // O,I
            if (V[y][x] == 'I' || V[y][x] == '?')
              now[nbit] += before[bit];
            if (V[y][x] == 'J' || V[y][x] == '?')
              now[nbit | 1] += before[bit]; // J
          }
        } else {
          if (bit & (1 << (w - 1))) {
            if (bit & 1) {
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit | (1 << 1)] += before[bit]; // O
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            } else {
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit] += before[bit]; // O
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            }
          } else {
            if (bit & 1) {
              if (V[y][x] == 'I' || V[y][x] == '?')
                now[nbit] += before[bit]; // I
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit | (1 << 1)] += before[bit]; // O
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            } else {
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit] += before[bit]; // O,I
              if (V[y][x] == 'I' || V[y][x] == '?')
                now[nbit] += before[bit];
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            }
          }
        }
      }
      swap(before, now);

      for (int i = 0; i < 1 << w; i++) {
        now[i] = 0;
        before[i] %= MOD;
      }
    }
  }

  int ans = 0;
  for (int i = 0; i < 1 << w; i++) {
    ans += before[i] % MOD;
  }
  ans %= MOD;
  cout << (res - ans) % MOD << endl;
}

int main() {
  while (cin >> h >> w) {
    solve();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <string.h>
#include <string>
#include <vector>
using namespace std;

int w, h;
const int MOD = 100000;

int dp[2][1 << 20];

void solve() {
  int res = 1;
  vector<string> V;
  for (int i = 0; i < h; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < s.size(); j++) {
      if (s[j] == '?')
        res *= 3;
      res %= MOD;
    }
    V.push_back(s);
  }

  if (w == 1 || h == 1) {
    cout << res << endl;
    return;
  }

  for (int y = 1; y < h; y++) {
    for (int x = 0; x < w - 1; x++) {
      if (V[y][x] == 'I' && V[y - 1][x] == 'J' && V[y - 1][x + 1] == 'O') {
        cout << res << endl;
        return;
      }
    }
  }

  if (res == 1) {
    cout << 0 << endl;
    return;
  }

  memset(dp, 0, sizeof(dp));

  int *before = dp[0];
  int *now = dp[1];

  // ÅãÌbitÍJÅ é©Ç¤©
  // »êÈOÍA©ªªJÅ©ÂEªOÅ é©

  memset(before, 0, sizeof(before));
  before[0] = 1;

  for (int y = 0; y < h; y++) {
    memset(now, 0, sizeof(now));
    for (int x = 0; x < w; x++) {

      for (int bit = 0; bit < 1 << w; bit++) {
        int nbit;
        nbit = bit & (~1);
        nbit = nbit << 1;
        nbit = nbit & (~(1 << w));

        if (x == 0) {
          if (bit & (1 << (w - 1))) {
            if (V[y][x] == 'O' || V[y][x] == '?')
              now[nbit] += before[bit]; // O;
            if (V[y][x] == 'J' || V[y][x] == '?')
              now[nbit | 1] += before[bit]; // J
          } else {
            if (V[y][x] == 'O' || V[y][x] == '?')
              now[nbit] += before[bit]; // O,I
            if (V[y][x] == 'I' || V[y][x] == '?')
              now[nbit] += before[bit];
            if (V[y][x] == 'J' || V[y][x] == '?')
              now[nbit | 1] += before[bit]; // J
          }
        } else {
          if (bit & (1 << (w - 1))) {
            if (bit & 1) {
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit | (1 << 1)] += before[bit]; // O
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            } else {
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit] += before[bit]; // O
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            }
          } else {
            if (bit & 1) {
              if (V[y][x] == 'I' || V[y][x] == '?')
                now[nbit] += before[bit]; // I
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit | (1 << 1)] += before[bit]; // O
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            } else {
              if (V[y][x] == 'O' || V[y][x] == '?')
                now[nbit] += before[bit]; // O,I
              if (V[y][x] == 'I' || V[y][x] == '?')
                now[nbit] += before[bit];
              if (V[y][x] == 'J' || V[y][x] == '?')
                now[nbit | 1] += before[bit]; // J
            }
          }
        }
      }
      swap(before, now);

      for (int i = 0; i < 1 << w; i++) {
        now[i] = 0;
        before[i] %= MOD;
      }
    }
  }

  int ans = 0;
  for (int i = 0; i < 1 << w; i++) {
    ans += before[i] % MOD;
  }
  ans %= MOD;
  cout << (res - ans) % MOD << endl;
}

int main() {
  while (cin >> h >> w) {
    solve();
  }
  return 0;
}