Problem p03300 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rrp(i, a, b) for (int i = (a); i >= (b); --i)
#define gc() getchar()
#define fir first
#define sec second
typedef pair<int, int> pii;
typedef double db;
typedef long long ll;
template <typename tp> inline void read(tp &x) {
  x = 0;
  char tmp;
  bool key = 0;
  for (tmp = gc(); !isdigit(tmp); tmp = gc())
    key = (tmp == '-');
  for (; isdigit(tmp); tmp = gc())
    x = (x << 3) + (x << 1) + (tmp ^ '0');
  if (key)
    x = -x;
}
template <typename tp> inline void ckmn(tp &x, tp y) { x = x < y ? x : y; }
template <typename tp> inline void ckmx(tp &x, tp y) { x = x < y ? y : x; }

const int N = 3010;
int n;
char str[N << 1];
struct data {
  int lp, rp, tp;
  bool operator<(const data &a) const { return lp < a.lp; }
} dat[N];
string dp[N];
int cnt, vis[N];
string doit(int l, int r) {
  string ret = "";
  if (dat[l].tp == 0) {
    int cur = 0;
    rep(i, l, r) {
      if (dat[i].lp > cur) {
        cur = dat[i].rp;
        ret += "ab";
      }
    }
  } else {
    rep(i, l, r) {
      rep(j, i, r) vis[dat[j].lp] = vis[dat[j].rp] = 1;
      string tmp = "";
      rep(j, 1, 2 * n) if (vis[j]) tmp += str[j];
      ret = max(ret, tmp);
      rep(j, i, r) vis[dat[j].lp] = vis[dat[j].rp] = 0;
    }
  }
  return ret;
}
int main() {
  read(n);
  scanf("%s", str + 1);
  for (int i = 1, j = 1; i <= 2 * n; ++i)
    if (str[i] == 'a')
      dat[j++].lp = i;
  for (int i = 1, j = 1; i <= 2 * n; ++i)
    if (str[i] == 'b')
      dat[j++].rp = i;
  rep(i, 1, n) if (dat[i].lp > dat[i].rp) {
    dat[i].tp = 1;
    swap(dat[i].lp, dat[i].rp);
  }
  sort(dat + 1, dat + n + 1);
  dp[0] = "";
  for (int i = 1, j = 1; i <= n; ++i) {
    j = i;
    while (j < n && dat[j + 1].lp < dat[j].rp)
      ++j;
    string tmp = doit(i, j);
    ++cnt;
    rep(k, 0, cnt - 1) dp[cnt] = max(dp[k] + tmp, dp[cnt]);
    i = j;
  }
  string ans = "";
  rep(i, 1, cnt) ans = max(ans, dp[i]);
  cout << ans << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rrp(i, a, b) for (int i = (a); i >= (b); --i)
#define gc() getchar()
#define fir first
#define sec second
typedef pair<int, int> pii;
typedef double db;
typedef long long ll;
template <typename tp> inline void read(tp &x) {
  x = 0;
  char tmp;
  bool key = 0;
  for (tmp = gc(); !isdigit(tmp); tmp = gc())
    key = (tmp == '-');
  for (; isdigit(tmp); tmp = gc())
    x = (x << 3) + (x << 1) + (tmp ^ '0');
  if (key)
    x = -x;
}
template <typename tp> inline void ckmn(tp &x, tp y) { x = x < y ? x : y; }
template <typename tp> inline void ckmx(tp &x, tp y) { x = x < y ? y : x; }

const int N = 3010;
int n;
char str[N << 1];
struct data {
  int lp, rp, tp;
  bool operator<(const data &a) const { return lp < a.lp; }
} dat[N];
string dp[N];
int cnt, vis[N << 1];
string doit(int l, int r) {
  string ret = "";
  if (dat[l].tp == 0) {
    int cur = 0;
    rep(i, l, r) {
      if (dat[i].lp > cur) {
        cur = dat[i].rp;
        ret += "ab";
      }
    }
  } else {
    rep(i, l, r) {
      rep(j, i, r) vis[dat[j].lp] = vis[dat[j].rp] = 1;
      string tmp = "";
      rep(j, 1, 2 * n) if (vis[j]) tmp += str[j];
      ret = max(ret, tmp);
      rep(j, i, r) vis[dat[j].lp] = vis[dat[j].rp] = 0;
    }
  }
  return ret;
}
int main() {
  read(n);
  scanf("%s", str + 1);
  for (int i = 1, j = 1; i <= 2 * n; ++i)
    if (str[i] == 'a')
      dat[j++].lp = i;
  for (int i = 1, j = 1; i <= 2 * n; ++i)
    if (str[i] == 'b')
      dat[j++].rp = i;
  rep(i, 1, n) if (dat[i].lp > dat[i].rp) {
    dat[i].tp = 1;
    swap(dat[i].lp, dat[i].rp);
  }
  sort(dat + 1, dat + n + 1);
  dp[0] = "";
  for (int i = 1, j = 1; i <= n; ++i) {
    j = i;
    while (j < n && dat[j + 1].lp < dat[j].rp)
      ++j;
    string tmp = doit(i, j);
    ++cnt;
    rep(k, 0, cnt - 1) dp[cnt] = max(dp[k] + tmp, dp[cnt]);
    i = j;
  }
  string ans = "";
  rep(i, 1, cnt) ans = max(ans, dp[i]);
  cout << ans << endl;
  return 0;
}