Problem p01551 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
using namespace std;

struct node {
  int len, ATCG;
  vector<string> V;
  node() {
    len = 0;
    ATCG = 0;
  }
};
map<string, node> M;

void rec(vector<int> &L, string S) {
  node &n = M[S];
  if (n.len == 1 && n.ATCG) {
    L.push_back(n.ATCG);
  } else {
    for (auto &children : n.V) {
      rec(L, children);
    }
  }
  return;
}
int DP[51][51][51][51];

int main() {
  int Na, Nt, Ng, Nc, m;
  cin >> Na >> Nt >> Ng >> Nc >> m;
  cin.ignore();
  string name, root;
  vector<string> S(m);
  for (int i = 0; i < m; i++)
    getline(cin, S[i]);
  for (int i = m - 1; i >= 0; i--) {
    stringstream ss(S[i]);
    string s;
    ss >> name;
    name.pop_back();
    if (!i)
      root = name;
    node &n = M[name];
    while (ss >> s) {
      if (M.find(s) == M.end()) {
        node &ns = M[s];
        ns.len = 1;
        for (auto c : s) {
          if (c == 'A')
            ns.ATCG += 1;
          if (c == 'T')
            ns.ATCG += 2;
          if (c == 'G')
            ns.ATCG += 4;
          if (c == 'C')
            ns.ATCG += 8;
        }
      }
      n.len += M[s].len;
      n.V.push_back(s);
    }
  }
  if (M[root].len != Na + Nt + Ng + Nc) {
    cout << 0 << endl;
    return 0;
  }
  vector<int> L;
  rec(L, root);
  // for(auto l:L)cout<<l<<endl;
  DP[0][0][0][0] = 1;
  int mod = 1e9 + 7;
  for (int i = 1; i <= L.size(); i++) {
    int ATCG = L[i - 1];
    // A
    if (ATCG & 1) {
      for (int A = 0; A < i && A < Na; A++) {
        for (int T = 0; A + T < i && T <= Nt; T++) {
          for (int G = 0; A + T + G < i && G <= Ng; G++) {
            int C = i - 1 - A - T - G;
            if (C > Nc)
              continue;
            DP[A + 1][T][G][C] += DP[A][T][G][C];
            if (DP[A + 1][T][G][C] >= mod)
              DP[A + 1][T][G][C] -= mod;
          }
        }
      }
    }
    // T
    if (ATCG & 2) {
      for (int A = 0; A < i && A <= Na; A++) {
        for (int T = 0; A + T < i && T < Nt; T++) {
          for (int G = 0; A + T + G < i && G <= Ng; G++) {
            int C = i - 1 - A - T - G;
            if (C > Nc)
              continue;
            DP[A][T + 1][G][C] += DP[A][T][G][C];
            if (DP[A][T + 1][G][C] >= mod)
              DP[A][T + 1][G][C] -= mod;
          }
        }
      }
    }
    // G
    if (ATCG & 4) {
      for (int A = 0; A < i && A <= Na; A++) {
        for (int T = 0; A + T < i && T <= Nt; T++) {
          for (int G = 0; A + T + G < i && G < Ng; G++) {
            int C = i - 1 - A - T - G;
            if (C > Nc)
              continue;
            DP[A][T][G + 1][C] += DP[A][T][G][C];
            if (DP[A][T][G + 1][C] >= mod)
              DP[A][T][G + 1][C] -= mod;
          }
        }
      }
    }
    // C
    if (ATCG & 8) {
      for (int A = 0; A < i && A <= Na; A++) {
        for (int T = 0; A + T < i && T <= Nt; T++) {
          for (int G = 0; A + T + G < i && G <= Ng; G++) {
            int C = i - 1 - A - T - G;
            if (C >= Nc)
              continue;
            DP[A][T][G][C + 1] += DP[A][T][G][C];
            if (DP[A][T][G][C + 1] >= mod)
              DP[A][T][G][C + 1] -= mod;
          }
        }
      }
    }
  }
  cout << DP[Na][Nt][Ng][Nc] << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
using namespace std;

struct node {
  int len, ATCG;
  vector<string> V;
  node() {
    len = 0;
    ATCG = 0;
  }
};
map<string, node> M;

void rec(vector<int> &L, string S) {
  node &n = M[S];
  if (n.len == 1 && n.ATCG) {
    L.push_back(n.ATCG);
  } else {
    for (auto &children : n.V) {
      rec(L, children);
    }
  }
  return;
}
int DP[51][51][51][51];

int main() {
  int Na, Nt, Ng, Nc, m;
  cin >> Na >> Nt >> Ng >> Nc >> m;
  cin.ignore();
  string name, root;
  vector<string> S(m);
  for (int i = 0; i < m; i++)
    getline(cin, S[i]);
  for (int i = m - 1; i >= 0; i--) {
    stringstream ss(S[i]);
    string s;
    ss >> name;
    name.pop_back();
    if (!i)
      root = name;
    node &n = M[name];
    while (ss >> s) {
      if (M.find(s) == M.end()) {
        node &ns = M[s];
        ns.len = 1;
        for (auto c : s) {
          if (c == 'A')
            ns.ATCG += 1;
          if (c == 'T')
            ns.ATCG += 2;
          if (c == 'G')
            ns.ATCG += 4;
          if (c == 'C')
            ns.ATCG += 8;
        }
      }
      n.len += M[s].len;
      n.V.push_back(s);
    }
  }
  if (M[root].len != Na + Nt + Ng + Nc) {
    cout << 0 << endl;
    return 0;
  }
  vector<int> L;
  rec(L, root);
  // for(auto l:L)cout<<l<<endl;
  DP[0][0][0][0] = 1;
  int mod = 1e9;
  for (int i = 1; i <= L.size(); i++) {
    int ATCG = L[i - 1];
    // A
    if (ATCG & 1) {
      for (int A = 0; A < i; A++) {
        for (int T = 0; A + T < i; T++) {
          for (int C = 0; A + T + C < i; C++) {
            int G = i - 1 - A - T - C;
            DP[A + 1][T][G][C] += DP[A][T][G][C];
            if (DP[A + 1][T][G][C] >= mod)
              DP[A + 1][T][G][C] -= mod;
          }
        }
      }
    }
    // T
    if (ATCG & 2) {
      for (int A = 0; A < i; A++) {
        for (int T = 0; A + T < i; T++) {
          for (int C = 0; A + T + C < i; C++) {
            int G = i - 1 - A - T - C;
            DP[A][T + 1][G][C] += DP[A][T][G][C];
            if (DP[A][T + 1][G][C] >= mod)
              DP[A][T + 1][G][C] -= mod;
          }
        }
      }
    }
    // G
    if (ATCG & 4) {
      for (int A = 0; A < i; A++) {
        for (int T = 0; A + T < i; T++) {
          for (int C = 0; A + T + C < i; C++) {
            int G = i - 1 - A - T - C;
            DP[A][T][G + 1][C] += DP[A][T][G][C];
            if (DP[A][T][G + 1][C] >= mod)
              DP[A][T][G + 1][C] -= mod;
          }
        }
      }
    }
    // C
    if (ATCG & 8) {
      for (int A = 0; A < i; A++) {
        for (int T = 0; A + T < i; T++) {
          for (int C = 0; A + T + C < i; C++) {
            int G = i - 1 - A - T - C;
            DP[A][T][G][C + 1] += DP[A][T][G][C];
            if (DP[A][T][G][C + 1] >= mod)
              DP[A][T][G][C + 1] -= mod;
          }
        }
      }
    }
  }
  cout << DP[Na][Nt][Ng][Nc] << endl;
  return 0;
}