Problem p00527 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAX_N 2200

int dp[MAX_N][MAX_N][2];
string S, T;
int a, b, g, h, maxn;

int main() {
  cin >> a >> b;
  cin >> S >> T;
  while (S.size() != MAX_N) {
    S += ' ';
  }
  while (T.size() != MAX_N) {
    T += ' ';
  }
  g = max(a, b);
  h = min(20, min(a, b));
  for (int i = 0; i <= h; i++) {
    for (int j = 0; j <= g; j++) {
      for (int k = 0; k <= g; k++) {
        if (S[j] == 'I') {
          dp[j][k][0] = max(dp[j][k][0], 1);
          if (S[j + 1] == 'O') {
            dp[j + 1][k][0] = max(dp[j + 1][k][0], dp[j][k][0] + 1);
          }
          if (T[k] == 'O') {
            dp[k][j + 1][1] = max(dp[k][j + 1][1], dp[j][k][0] + 1);
          }
        } else if (S[j] == 'O') {
          if (S[j + 1] == 'I') {
            dp[j + 1][k][0] = max(dp[j + 1][k][0], dp[j][k][0] + 1);
          }
          if (T[k] == 'I') {
            dp[k][j + 1][1] = max(dp[k][j + 1][1], dp[j][k][0] + 1);
          }
        }
        if (T[k] == 'I') {
          dp[k][j][1] = max(dp[k][j][1], 1);
          if (T[k + 1] == 'O') {
            dp[k + 1][j][1] = max(dp[k + 1][j][1], dp[k][j][1] + 1);
          }
          if (S[j] == 'O') {
            dp[j][k + 1][0] = max(dp[j][k + 1][0], dp[k][j][1] + 1);
          }
        } else if (T[k] == 'O') {
          if (T[k + 1] == 'I') {
            dp[k + 1][j][1] = max(dp[k + 1][j][1], dp[k][j][1] + 1);
          }
          if (S[j] == 'I') {
            dp[j][k + 1][0] = max(dp[j][k + 1][0], dp[k][j][1] + 1);
          }
        }
      }
    }
  }
  for (int i = 0; i < MAX_N; i++) {
    for (int j = 0; j < MAX_N; j++) {
      if (dp[i][j][0] % 2 == 1) {
        maxn = max(maxn, dp[i][j][0]);
      }
      if (dp[i][j][1] % 2 == 1) {
        maxn = max(maxn, dp[i][j][1]);
      }
    }
  }
  cout << maxn << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAX_N 2200

int dp[MAX_N][MAX_N][2];
string S, T;
int a, b, g, h, maxn;

int main() {
  cin >> a >> b;
  cin >> S >> T;
  while (S.size() != MAX_N) {
    S += ' ';
  }
  while (T.size() != MAX_N) {
    T += ' ';
  }
  g = max(a, b);
  h = min(17, min(a, b));
  for (int i = 0; i <= h; i++) {
    for (int j = 0; j <= g; j++) {
      for (int k = 0; k <= g; k++) {
        if (S[j] == 'I') {
          dp[j][k][0] = max(dp[j][k][0], 1);
          if (S[j + 1] == 'O') {
            dp[j + 1][k][0] = max(dp[j + 1][k][0], dp[j][k][0] + 1);
          }
          if (T[k] == 'O') {
            dp[k][j + 1][1] = max(dp[k][j + 1][1], dp[j][k][0] + 1);
          }
        } else if (S[j] == 'O') {
          if (S[j + 1] == 'I') {
            dp[j + 1][k][0] = max(dp[j + 1][k][0], dp[j][k][0] + 1);
          }
          if (T[k] == 'I') {
            dp[k][j + 1][1] = max(dp[k][j + 1][1], dp[j][k][0] + 1);
          }
        }
        if (T[k] == 'I') {
          dp[k][j][1] = max(dp[k][j][1], 1);
          if (T[k + 1] == 'O') {
            dp[k + 1][j][1] = max(dp[k + 1][j][1], dp[k][j][1] + 1);
          }
          if (S[j] == 'O') {
            dp[j][k + 1][0] = max(dp[j][k + 1][0], dp[k][j][1] + 1);
          }
        } else if (T[k] == 'O') {
          if (T[k + 1] == 'I') {
            dp[k + 1][j][1] = max(dp[k + 1][j][1], dp[k][j][1] + 1);
          }
          if (S[j] == 'I') {
            dp[j][k + 1][0] = max(dp[j][k + 1][0], dp[k][j][1] + 1);
          }
        }
      }
    }
  }
  for (int i = 0; i < MAX_N; i++) {
    for (int j = 0; j < MAX_N; j++) {
      if (dp[i][j][0] % 2 == 1) {
        maxn = max(maxn, dp[i][j][0]);
      }
      if (dp[i][j][1] % 2 == 1) {
        maxn = max(maxn, dp[i][j][1]);
      }
    }
  }
  cout << maxn << endl;
  return 0;
}