Problem p03165 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define optimize                                                               \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(NULL);                                                               \
  cout.tie(NULL)
#define INF 2000000020LL
#define ALL(x) x.begin(), x.end()
#define UNIQUE(c) (c).resize(unique(ALL(c)) - (c).begin())
#define REP(i, a, b) for (int i = (a); i <= (b); i++)
#define POS(n, x) (lower_bound(ALL(n), x) - (n).begin())
#define ll long long
#define ld long double
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pii>
#define PB push_back
#define EB emplace_back
#define MOD 1000000007
#define PRIME 101
#define MAXN 3030
#define MAXL 23
#define endl '\n'

using namespace std;

// (1 + sqrt(5)) / 2
const ld GOLDEN_RATIO = 1.6180339887498949025257388711906969547271728515625;
const ld PI = 2.0 * acos(0.0);
const int BLOCK = 333;

int dp[MAXN][MAXN];

string S, T;

int solve(int i, int j) {
  if (i < 0 || j < 0)
    return 0;
  if (dp[i][j] != -1)
    return dp[i][j];

  return dp[i][j] = (S[i] == T[j] ? 1 + solve(i - 1, j - 1)
                                  : max(solve(i - 1, j), solve(i, j - 1)));
}

int main(int argc, char const *argv[]) {
  optimize;

  memset(dp, -1, sizeof dp);

  cin >> S >> T;

  int N = S.length() - 1;
  int M = T.length() - 1;

  solve(N, M);

  string ans = "";

  while (N >= 0 && M >= 0) {
    if (S[N] == T[M]) {
      ans += S[N];

      N--;
      M--;
    } else {
      if (dp[N - 1][M] > dp[N][M - 1])
        N--;
      else
        M--;
    }
  }

  reverse(ALL(ans));

  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define optimize                                                               \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(NULL);                                                               \
  cout.tie(NULL)
#define INF 2000000020LL
#define ALL(x) x.begin(), x.end()
#define UNIQUE(c) (c).resize(unique(ALL(c)) - (c).begin())
#define REP(i, a, b) for (int i = (a); i <= (b); i++)
#define POS(n, x) (lower_bound(ALL(n), x) - (n).begin())
#define ll long long
#define ld long double
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pii>
#define PB push_back
#define EB emplace_back
#define MOD 1000000007
#define PRIME 101
#define MAXN 3030
#define MAXL 23
#define endl '\n'

using namespace std;

// (1 + sqrt(5)) / 2
const ld GOLDEN_RATIO = 1.6180339887498949025257388711906969547271728515625;
const ld PI = 2.0 * acos(0.0);
const int BLOCK = 333;

int dp[MAXN][MAXN];

string S, T;

int solve(int i, int j) {
  if (i < 0 || j < 0)
    return 0;
  if (dp[i][j] != -1)
    return dp[i][j];

  return dp[i][j] = (S[i] == T[j] ? 1 + solve(i - 1, j - 1)
                                  : max(solve(i - 1, j), solve(i, j - 1)));
}

int main(int argc, char const *argv[]) {
  optimize;

  memset(dp, -1, sizeof dp);

  cin >> S >> T;

  int N = S.length() - 1;
  int M = T.length() - 1;

  solve(N, M);

  string ans = "";

  while (N >= 0 && M >= 0) {
    if (S[N] == T[M]) {
      ans += S[N];

      N--;
      M--;
    } else {
      if (!N)
        M--;
      else if (!M)
        N--;
      else if (dp[N - 1][M] > dp[N][M - 1])
        N--;
      else
        M--;
    }
  }

  reverse(ALL(ans));

  cout << ans << endl;

  return 0;
}