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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
int n;
string s;
/*
map<int,int> dp[444][2];
int solve(int l,int jf,int bit){
  if(dp[l][jf].find(bit) != dp[l][jf].end()) return dp[l][jf][bit];
  if(l == (int)s.size()) return 1;

  int res = 0;
  if(s[l] == '?'){
    res += solve(l+1,1,(bit<<1) & ((1<<n)-1)); // J
    res += solve(l+1,0,((bit<<1) & ((1<<n)-1)) | ((jf)?1:0)); //O
    if(!(bit & 1<<(n-2)) || !((l+1)%n)) res += solve(l+1,0,(bit<<1) &
((1<<n)-1)); //I }else if(s[l] == 'J'){ res += solve(l+1,1,(bit<<1) &
((1<<n)-1)); // J }else if(s[l] == 'O'){ res += solve(l+1,0,((bit<<1) &
((1<<n)-1)) | ((jf)?1:0)); //O }else if(s[l] == 'I' && (!(bit & 1<<(n-2)) ||
!((l+1)%n))){ res += solve(l+1,0,(bit<<1) & ((1<<n)-1)); //I
  }
  return dp[l][jf][bit] = res % 100000;
}
*/
int num[1 << 22];
vector<int> nm;
int a;
void mk_num(int i, int f) {
  if (i > 20) {
    num[a] = (int)nm.size();
    nm.push_back(a);
    return;
  }
  a <<= 1;
  mk_num(i + 1, 0);
  if (!f) {
    a |= 1;
    mk_num(i + 1, 1);
  }
  a >>= 1;
  return;
}

int dp[2][33333][2];
int main(void) {
  int m;
  cin >> m >> n;
  for (int i = 0; i < m; i++) {
    string ss;
    cin >> ss;
    s += ss;
  }
  mk_num(0, 0);
  int M = 1;
  for (int i = 0; i < (int)s.size(); i++) {
    if (s[i] == '?') {
      M *= 3;
      M %= 100000;
    }
  }
  dp[0][0][0] = 1;
  for (int i = 0; i < (int)s.size(); i++) {
    int now = i % 2;
    int next = (i + 1) % 2;
    memset(dp[next], 0, sizeof(dp[next]));
    for (int j = 0; j < (int)nm.size(); j++) {
      for (int k = 0; k < 2; k++) {
        dp[now][j][k] %= 100000;
        if (s[i] == '?' || s[i] == 'J')
          dp[next][num[(nm[j] << 1) & ((1 << n) - 1)]][1] += dp[now][j][k];
        if (s[i] == '?' || s[i] == 'O')
          dp[next][num[(nm[j] << 1) & ((1 << n) - 1) | ((k) ? 1 : 0)]][0] +=
              dp[now][j][k];
        if ((s[i] == '?' || s[i] == 'I') &&
            (!(nm[j] & 1 << (n - 2)) || !((i + 1) % n)))
          dp[next][num[(nm[j] << 1) & ((1 << n) - 1)]][0] += dp[now][j][k];
      }
    }
  }
  int res = 0;
  for (int j = 0; j < (int)nm.size(); j++) {
    for (int k = 0; k < 2; k++) {
      res += dp[(int)s.size() % 2][j][k];
      res %= 100000;
    }
  }
  cout << (M - res + 100000) % 100000 << endl;
  // cout << M - solve(0,0,0) << endl;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
using namespace std;
int n;
string s;
map<int, int> dp[444][2];
int solve(int l, int jf, int bit) {
  if (dp[l][jf].find(bit) != dp[l][jf].end())
    return dp[l][jf][bit];
  if (l == (int)s.size())
    return 1;

  int res = 0;
  if (s[l] == '?') {
    res += solve(l + 1, 1, (bit << 1) & ((1 << n) - 1));                    // J
    res += solve(l + 1, 0, ((bit << 1) & ((1 << n) - 1)) | ((jf) ? 1 : 0)); // O
    if (!(bit & 1 << (n - 2)) || !((l + 1) % n))
      res += solve(l + 1, 0, (bit << 1) & ((1 << n) - 1)); // I
  } else if (s[l] == 'J') {
    res += solve(l + 1, 1, (bit << 1) & ((1 << n) - 1)); // J
  } else if (s[l] == 'O') {
    res += solve(l + 1, 0, ((bit << 1) & ((1 << n) - 1)) | ((jf) ? 1 : 0)); // O
  } else if (s[l] == 'I' && (!(bit & 1 << (n - 2)) || !((l + 1) % n))) {
    res += solve(l + 1, 0, (bit << 1) & ((1 << n) - 1)); // I
  }
  return dp[l][jf][bit] = res % 100000;
}
int main(void) {
  int m;
  cin >> m >> n;
  for (int i = 0; i < m; i++) {
    string ss;
    cin >> ss;
    s += ss;
  }
  int M = 1;
  for (int i = 0; i < (int)s.size(); i++) {
    if (s[i] == '?') {
      M *= 3;
      M %= 100000;
    }
  }
  cout << M - solve(0, 0, 0) << endl;
}