Problem p03165 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define nl '\n'
#define vec vector<ll>
#define pr pair<ll, ll>
#define vecp vector<pr>
#define pq priority_queue<ll>
#define pqp priority_queue<pr>
#define ff first
#define ss second
#define f(i, a, b) for (ll i = (ll)a; i < (ll)b; i++)
#define rf(i, a, b) for (ll i = (ll)a; i >= (ll)b; i--)
#define fa(x, v) for (auto x : v)
#define fast                                                                   \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
#define max4(a, b, c, d) max(a, max3(b, c, d))
#define min4(a, b, c, d) min(a, min3(b, c, d))
#define PI 3.14159265
const ll MOD = 1000000007;
ll powerm(ll a, ll b, ll MOD) {
  a %= MOD;
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = res * a % MOD;
    a = a * a % MOD;
    b >>= 1;
  }
  return res;
}
ll power(ll a, ll b) {

  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = res * a;
    a = a * a;
    b >>= 1;
  }
  return res;
}
ll binarySearch(ll a[], ll low, ll high, ll key) {
  while (low <= high) {
    ll mid = low + ((high - low) / 2);
    if (a[mid] < key) {
      low = mid + 1;
    } else if (a[mid] > key) {
      high = mid - 1;
    } else {
      return mid;
    }
  }
  return -1;
}
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
vec sieve;
void Sieve(int N) {
  const ll maxn = N + 1;
  sieve.resize(maxn);
  f(i, 0, maxn) sieve[i] = i;
  sieve[1] = -1;
  sieve[0] = -1;
  f(i, 2, maxn) if (i == sieve[i]) for (ll j = 2 * i; j < maxn;
                                        j += i) if (sieve[j] == j) sieve[j] = i;
}
ll dp[3001][3001];
ll recur(ll n, ll m, string s1, string s2) {
  if (dp[n][m] != -1)
    return dp[n][m];
  if (n == 0 || m == 0) {
    dp[n][m] = 0;
    return 0;
  }
  if (s1[n - 1] == s2[m - 1])
    dp[n][m] = 1 + recur(n - 1, m - 1, s1, s2);
  else
    dp[n][m] = max(recur(n - 1, m, s1, s2), recur(n, m - 1, s1, s2));

  return dp[n][m];
}
int main() {
  fast string s1, s2;
  cin >> s1 >> s2;
  ll n = s1.length();
  ll m = s2.length();
  f(i, 0, n + 1) f(j, 0, m + 1) dp[i][j] = -1;
  ll lcs = recur(n, m, s1, s2);
  string final = "";
  if (lcs >= 1) {
    while (n > 0 && m > 0) {
      if (s1[n - 1] == s2[m - 1]) {
        final += s1[n - 1];
        m--;
        n--;
      } else {
        if (dp[n - 1][m] > dp[n][m - 1]) {
          n--;
        } else {
          m--;
        }
      }
    }
    for (ll i = final.length() - 1; i >= 0; i--) {
      cout << final[i];
    }
  } else
    cout << "" << nl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define nl '\n'
#define vec vector<ll>
#define pr pair<ll, ll>
#define vecp vector<pr>
#define pq priority_queue<ll>
#define pqp priority_queue<pr>
#define ff first
#define ss second
#define f(i, a, b) for (ll i = (ll)a; i < (ll)b; i++)
#define rf(i, a, b) for (ll i = (ll)a; i >= (ll)b; i--)
#define fa(x, v) for (auto x : v)
#define fast                                                                   \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
#define max4(a, b, c, d) max(a, max3(b, c, d))
#define min4(a, b, c, d) min(a, min3(b, c, d))
#define PI 3.14159265
const ll MOD = 1000000007;
ll powerm(ll a, ll b, ll MOD) {
  a %= MOD;
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = res * a % MOD;
    a = a * a % MOD;
    b >>= 1;
  }
  return res;
}
ll power(ll a, ll b) {

  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = res * a;
    a = a * a;
    b >>= 1;
  }
  return res;
}
ll binarySearch(ll a[], ll low, ll high, ll key) {
  while (low <= high) {
    ll mid = low + ((high - low) / 2);
    if (a[mid] < key) {
      low = mid + 1;
    } else if (a[mid] > key) {
      high = mid - 1;
    } else {
      return mid;
    }
  }
  return -1;
}
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
vec sieve;
void Sieve(int N) {
  const ll maxn = N + 1;
  sieve.resize(maxn);
  f(i, 0, maxn) sieve[i] = i;
  sieve[1] = -1;
  sieve[0] = -1;
  f(i, 2, maxn) if (i == sieve[i]) for (ll j = 2 * i; j < maxn;
                                        j += i) if (sieve[j] == j) sieve[j] = i;
}
ll dp[3001][3001];
ll recur(ll n, ll m, string &s1, string &s2) {
  if (dp[n][m] != -1)
    return dp[n][m];
  if (n == 0 || m == 0) {
    dp[n][m] = 0;
    return 0;
  }
  if (s1[n - 1] == s2[m - 1])
    dp[n][m] = 1 + recur(n - 1, m - 1, s1, s2);
  else
    dp[n][m] = max(recur(n - 1, m, s1, s2), recur(n, m - 1, s1, s2));

  return dp[n][m];
}
int main() {
  fast string s1, s2;
  cin >> s1 >> s2;
  ll n = s1.length();
  ll m = s2.length();
  f(i, 0, n + 1) f(j, 0, m + 1) dp[i][j] = -1;
  ll lcs = recur(n, m, s1, s2);
  string final = "";
  if (lcs >= 1) {
    while (n > 0 && m > 0) {
      if (s1[n - 1] == s2[m - 1]) {
        final += s1[n - 1];
        m--;
        n--;
      } else {
        if (dp[n - 1][m] > dp[n][m - 1]) {
          n--;
        } else {
          m--;
        }
      }
    }
    for (ll i = final.length() - 1; i >= 0; i--) {
      cout << final[i];
    }
  } else
    cout << "" << nl;
  return 0;
}