Problem p03088 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define FastRead                                                               \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define ll long long int
#define ld long double
#define FOR(i, a, n) for (int i = (a); i <= (n); ++i)
#define RFOR(i, a, n) for (int i = (n); i >= (a); --i)
#define FI(i, n) for (int i = 0; i < (n); ++i)
#define ZERO(a) memset((a), 0, sizeof((a)))
#define f first
// #define s second
#define pb push_back
#define mk make_pair
#define all(g) g.begin(), g.end()
int fastMax(int x, int y) { return (((y - x) >> (32 - 1)) & (x ^ y)) ^ y; }
int fastMin(int x, int y) { return (((y - x) >> (32 - 1)) & (x ^ y)) ^ x; }

// #include <ext/pb_ds/assoc_container.hpp> // Common file
// #include <ext/pb_ds/tree_policy.hpp>     // Including
// tree_order_statistics_node_updat using namespace __gnu_pbds; typedef tree<ll,
// null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
// ordered_set;

// I am questioning life and universe and
// everything else after looking at this

const ll MAXN = 101;
ll dp[MAXN][5][5][5][5][5][2];
const ll MOD = 1e9 + 7;
map<char, ll> m;
ll n;
ll rec(ll idx, ll prev0, ll prev1, ll prev2, ll prev3, ll prev4, ll check) {
  if (idx == n + 1) {
    if (prev1 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
      return 0;
    else if (prev1 == m['A'] && prev2 == m['C'] && prev3 == m['G'])
      return 0;
    else if (prev1 == m['G'] && prev2 == m['A'] && prev3 == m['C'])
      return 0;
    else if (prev0 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
      return 0;
    else if (prev1 == m['A'] && prev2 == m['G'] && prev4 == m['C'])
      return 0;

    else if (prev2 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
      return 0;
    else if (prev2 == m['A'] && prev3 == m['C'] && prev4 == m['G'])
      return 0;
    else if (prev2 == m['G'] && prev3 == m['A'] && prev4 == m['C'])
      return 0;
    else if (prev1 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
      return 0;
    else if (check)
      return 0;
    else
      return 1;
  }

  if (prev1 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
    check = true;
  else if (prev1 == m['A'] && prev2 == m['C'] && prev3 == m['G'])
    check = true;
  else if (prev1 == m['G'] && prev2 == m['A'] && prev3 == m['C'])
    check = true;
  else if (prev0 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
    check = true;
  else if (prev1 == m['A'] && prev2 == m['G'] && prev4 == m['C'])
    check = true;
  else if (prev2 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
    check = true;
  else if (prev2 == m['A'] && prev3 == m['C'] && prev4 == m['G'])
    check = true;
  else if (prev2 == m['G'] && prev3 == m['A'] && prev4 == m['C'])
    check = true;
  else if (prev1 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
    check = true;

  ll &ans = dp[idx][prev0][prev1][prev2][prev3][prev4][check];

  if (ans != -1)
    return ans;

  ans = 0;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['A'], check)) % MOD;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['G'], check)) % MOD;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['C'], check)) % MOD;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['T'], check)) % MOD;
  return ans;
}

void solve() {
  m['A'] = 0, m['G'] = 1, m['C'] = 2, m['T'] = 3;

  cin >> n;
  memset(dp, -1, sizeof(dp));

  ll ans = rec(1, 4, 4, 4, 4, 4, 0);
  cout << ans << endl;
}

signed main() {

#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif

  FastRead;

  ll t;
  t = 1;
  // cin>>t;
  FOR(tt, 1, t) { solve(); }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define FastRead                                                               \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define ll long long int
#define ld long double
#define FOR(i, a, n) for (int i = (a); i <= (n); ++i)
#define RFOR(i, a, n) for (int i = (n); i >= (a); --i)
#define FI(i, n) for (int i = 0; i < (n); ++i)
#define ZERO(a) memset((a), 0, sizeof((a)))
#define f first
// #define s second
#define pb push_back
#define mk make_pair
#define all(g) g.begin(), g.end()
int fastMax(int x, int y) { return (((y - x) >> (32 - 1)) & (x ^ y)) ^ y; }
int fastMin(int x, int y) { return (((y - x) >> (32 - 1)) & (x ^ y)) ^ x; }

// #include <ext/pb_ds/assoc_container.hpp> // Common file
// #include <ext/pb_ds/tree_policy.hpp>     // Including
// tree_order_statistics_node_updat using namespace __gnu_pbds; typedef tree<ll,
// null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
// ordered_set;

// I am questioning life and universe and
// everything else after looking at this

const ll MAXN = 101;
ll dp[MAXN][5][5][5][5][5][2];
const ll MOD = 1e9 + 7;
map<char, ll> m;
ll n;
ll rec(ll idx, ll prev0, ll prev1, ll prev2, ll prev3, ll prev4, ll check) {
  if (idx == n + 1) {
    if (prev1 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
      return 0;
    else if (prev1 == m['A'] && prev2 == m['C'] && prev3 == m['G'])
      return 0;
    else if (prev1 == m['G'] && prev2 == m['A'] && prev3 == m['C'])
      return 0;
    else if (prev0 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
      return 0;
    else if (prev1 == m['A'] && prev2 == m['G'] && prev4 == m['C'])
      return 0;

    else if (prev2 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
      return 0;
    else if (prev2 == m['A'] && prev3 == m['C'] && prev4 == m['G'])
      return 0;
    else if (prev2 == m['G'] && prev3 == m['A'] && prev4 == m['C'])
      return 0;
    else if (prev1 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
      return 0;
    else if (check)
      return 0;
    else
      return 1;
  }

  if (prev1 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
    check = true;
  else if (prev1 == m['A'] && prev2 == m['C'] && prev3 == m['G'])
    check = true;
  else if (prev1 == m['G'] && prev2 == m['A'] && prev3 == m['C'])
    check = true;
  else if (prev0 == m['A'] && prev2 == m['G'] && prev3 == m['C'])
    check = true;
  else if (prev1 == m['A'] && prev2 == m['G'] && prev4 == m['C'])
    check = true;
  else if (prev2 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
    check = true;
  else if (prev2 == m['A'] && prev3 == m['C'] && prev4 == m['G'])
    check = true;
  else if (prev2 == m['G'] && prev3 == m['A'] && prev4 == m['C'])
    check = true;
  else if (prev1 == m['A'] && prev3 == m['G'] && prev4 == m['C'])
    check = true;

  ll &ans = dp[idx][prev0][prev1][prev2][prev3][prev4][check];

  if (ans != -1)
    return ans;

  ans = 0;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['A'], check)) % MOD;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['G'], check)) % MOD;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['C'], check)) % MOD;
  ans = (ans + rec(idx + 1, prev1, prev2, prev3, prev4, m['T'], check)) % MOD;
  return ans;
}

void solve() {
  m['A'] = 0, m['G'] = 1, m['C'] = 2, m['T'] = 3;

  cin >> n;
  memset(dp, -1, sizeof(dp));

  ll ans = rec(1, 4, 4, 4, 4, 4, 0);
  cout << ans << endl;
}

signed main() {

  FastRead;

  ll t;
  t = 1;
  // cin>>t;
  FOR(tt, 1, t) { solve(); }
}