Problem p03165 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

// using namespace __gnu_pbds;
using namespace std;

// macros
#define ordered_set                                                            \
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
#define ld long double
#define pb push_back
#define f first
#define s second
#define IOS                                                                    \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define ll long long
#define ull unsigned long long
#define watch(x) cout << "debug : " << #x << " -> " << x << endl;

// globals
ll const mod = 1e9 + 7;
ll const size_1d = 1e6 + 7;
ll const size_2d = 3 * (1e3 + 7);

// functions
ll power(ll x, ll y, ll mod = 2e18) {
  ll ans = 1;
  x %= mod;
  while (y) {
    if (y & 1)
      ans = (x * ans) % mod;
    x = (x * x) % mod;
    y >>= 1;
  }
  return ans;
}
ll modInverse(ll a, ll m) {
  ll m0 = m;
  ll y = 0, x = 1;
  if (m == 1)
    return 0;
  while (a > 1) {
    ll q = a / m;
    ll t = m;
    m = a % m, a = t;
    t = y;
    y = x - q * y;
    x = t;
  }
  if (x < 0)
    x += m0;
  return x;
}
ll gcdext(ll a, ll b, ll *x = 0, ll *y = 0) {
  if (a == 0) {
    *x = 0;
    *y = 1;
    return b;
  }
  ll x1, y1;
  ll gcd1 = gcdext(b % a, a, &x1, &y1);
  *x = y1 - (b / a) * x1;
  *y = x1;
  return gcd1;
}
int randomize() { return (rand() % 10000); }

// CODE STARTS HERE
int dp[size_2d][size_2d];

int main() {
  IOS;

  string s1, s2;
  cin >> s1 >> s2;
  for (int i = 0; i < s1.length(); ++i) {
    if (s1[i] == s2[0])
      dp[i][0] = 1;
    else if (i != 0)
      dp[i][0] = dp[i - 1][0];
  }
  for (int i = 0; i < s2.length(); ++i) {
    if (s2[i] == s1[0])
      dp[0][i] = 1;
    else if (i != 0)
      dp[0][i] = dp[0][i - 1];
  }
  for (int i = 1; i < s1.length(); ++i) {
    for (int j = 1; j < s2.length(); ++j) {
      if (s1[i] == s2[j]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;
      } else {
        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
      }
    }
  }
  // cout << dp[s1.length()-1][s2.length()-1] << endl;
  int index = dp[s1.length() - 1][s2.length() - 1];
  if (index == 0)
    return cout << "" << endl, 0;
  char lcs[index + 1];
  lcs[index] = ' ';
  int i = s1.length() - 1, j = s2.length() - 1;
  while (i >= 0 && j >= 0) {
    if (s1[i] == s2[j]) {
      lcs[index - 1] = s1[i];
      i--;
      j--;
      index--;
    } else if (i == 0 && j != 0) {
      j--;
    } else if (i != 0 && j == 0) {
      i--;
    } else if (dp[i - 1][j] > dp[i][j - 1])
      i--;
    else
      j--;
  }
  int count = 1;
  for (auto &m : lcs) {
    if (count > dp[s1.length() - 1][s2.length() - 1])
      break;
    else
      cout << m;
    count++;
  }
  cout << endl;
  // cout << lcs << endl;
  // for (int i = 0; i < s1.length(); ++i)
  // {
  //   for (int j = 0; j < s2.length(); ++j)
  //   {
  //     cout << dp[i][j] << " ";
  //   }
  //   cout << endl;
  // }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

// using namespace __gnu_pbds;
using namespace std;

// macros
#define ordered_set                                                            \
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
#define ld long double
#define pb push_back
#define f first
#define s second
#define IOS                                                                    \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define ll long long
#define ull unsigned long long
#define watch(x) cout << "debug : " << #x << " -> " << x << endl;

// globals
ll const mod = 1e9 + 7;
ll const size_1d = 1e6 + 7;
ll const size_2d = 3 * (1e3 + 7);

// functions
ll power(ll x, ll y, ll mod = 2e18) {
  ll ans = 1;
  x %= mod;
  while (y) {
    if (y & 1)
      ans = (x * ans) % mod;
    x = (x * x) % mod;
    y >>= 1;
  }
  return ans;
}
ll modInverse(ll a, ll m) {
  ll m0 = m;
  ll y = 0, x = 1;
  if (m == 1)
    return 0;
  while (a > 1) {
    ll q = a / m;
    ll t = m;
    m = a % m, a = t;
    t = y;
    y = x - q * y;
    x = t;
  }
  if (x < 0)
    x += m0;
  return x;
}
ll gcdext(ll a, ll b, ll *x = 0, ll *y = 0) {
  if (a == 0) {
    *x = 0;
    *y = 1;
    return b;
  }
  ll x1, y1;
  ll gcd1 = gcdext(b % a, a, &x1, &y1);
  *x = y1 - (b / a) * x1;
  *y = x1;
  return gcd1;
}
int randomize() { return (rand() % 10000); }

// CODE STARTS HERE
int dp[size_2d][size_2d];

int main() {
  IOS;

  string s1, s2;
  cin >> s1 >> s2;
  for (int i = 0; i < s1.length(); ++i) {
    if (s1[i] == s2[0])
      dp[i][0] = 1;
    else if (i != 0)
      dp[i][0] = dp[i - 1][0];
  }
  for (int i = 0; i < s2.length(); ++i) {
    if (s2[i] == s1[0])
      dp[0][i] = 1;
    else if (i != 0)
      dp[0][i] = dp[0][i - 1];
  }
  for (int i = 1; i < s1.length(); ++i) {
    for (int j = 1; j < s2.length(); ++j) {
      if (s1[i] == s2[j]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;
      } else {
        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
      }
    }
  }
  // cout << dp[s1.length()-1][s2.length()-1] << endl;
  int index = dp[s1.length() - 1][s2.length() - 1];
  if (index == 0)
    return cout << "" << endl, 0;
  char lcs[index + 1];
  lcs[index] = ' ';
  int i = s1.length() - 1, j = s2.length() - 1;
  while (i >= 0 && j >= 0) {
    if (s1[i] == s2[j]) {
      lcs[index - 1] = s1[i];
      i--;
      j--;
      index--;
    } else if (i == 0 && j != 0) {
      j--;
    } else if (i != 0 && j == 0) {
      i--;
    } else if (i == 0 && j == 0) {
      break;
    } else if (dp[i - 1][j] > dp[i][j - 1])
      i--;
    else
      j--;
  }
  int count = 1;
  for (auto &m : lcs) {
    if (count > dp[s1.length() - 1][s2.length() - 1])
      break;
    else
      cout << m;
    count++;
  }
  cout << endl;
  // cout << lcs << endl;
  // for (int i = 0; i < s1.length(); ++i)
  // {
  //   for (int j = 0; j < s2.length(); ++j)
  //   {
  //     cout << dp[i][j] << " ";
  //   }
  //   cout << endl;
  // }
  return 0;
}