Problem p01551 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

using namespace std;

const string buff = "ATGC";
const int mod = 1e9 + 7;

vector<pair<int, int>> toto[50];
vector<int> order;

int dp2[52][52][52];
int dp3[52][52][52];

void dfs(int idx) {
  for (auto &to : toto[idx]) {
    if (to.first)
      dfs(to.second);
    else
      order.push_back(to.second);
  }
}

int main() {
  int Na, Nt, Ng, Nc, M;
  string s[50];

  cin >> Na >> Nt >> Ng >> Nc;
  int sum = Na + Nt + Ng + Nc;
  cin >> M;
  cin.ignore();
  for (int i = 0; i < M; i++)
    getline(cin, s[i]);

  map<string, int> convert;
  for (int i = M - 1; i >= 0; i--) {
    convert[s[i].substr(0, s[i].find(':'))] = i;
  }

  int dp[50] = {};
  for (int i = M - 1; i >= 0; i--) {
    string ss = s[i].substr(s[i].find(':') + 2);
    vector<string> splits;
    string curr;
    for (int j = 0; j <= ss.size(); j++) {
      if (j == ss.size() || ss[j] == ' ')
        splits.push_back(curr), curr = "";
      else
        curr += ss[j];
    }
    for (auto &t : splits) {
      if (t[0] == '[') {
        int mask = 0;
        for (int j = 0; j < buff.size(); j++) {
          if (t.find(buff[j]) != string::npos) {
            mask |= 1 << j;
          }
        }
        toto[i].emplace_back(0, mask);
        dp[i] = min(sum + 1, dp[i] + 1);
      } else {
        toto[i].emplace_back(1, convert[t]);
        dp[i] = min(sum + 1, dp[i] + dp[convert[t]]);
      }
    }
  }

  if (dp[0] != sum) {
    cout << 0 << endl;
  } else {
    dfs(0);

    dp2[0][0][0] = 1;
    for (int bit : order) {
      memset(dp3, 0, sizeof(dp3));
      for (int i = 0; i <= 50; i++) {
        for (int j = 0; j <= 50; j++) {
          for (int k = 0; k <= 50; k++) {
            if ((bit >> 0) & 1)
              (dp3[i + 1][j][k] += dp2[i][j][k]) %= mod;
            if ((bit >> 1) & 1)
              (dp3[i][j + 1][k] += dp2[i][j][k]) %= mod;
            if ((bit >> 2) & 1)
              (dp3[i][j][k + 1] += dp2[i][j][k]) %= mod;
            if ((bit >> 3) & 1)
              (dp3[i][j][k] += dp2[i][j][k]) %= mod;
          }
        }
      }
      swap(dp2, dp3);
    }
    cout << dp2[Na][Nt][Ng] << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const string buff = "ATGC";
const int mod = 1e9 + 7;

vector<pair<int, int>> toto[50];
vector<int> order;

int dp2[52][52][52][52];
int dp3[52][52][52][52];

void dfs(int idx) {
  for (auto &to : toto[idx]) {
    if (to.first)
      dfs(to.second);
    else
      order.push_back(to.second);
  }
}

int main() {
  int Na, Nt, Ng, Nc, M;
  string s[50];

  cin >> Na >> Nt >> Ng >> Nc;
  int sum = Na + Nt + Ng + Nc;
  cin >> M;
  cin.ignore();
  for (int i = 0; i < M; i++)
    getline(cin, s[i]);

  map<string, int> convert;
  for (int i = M - 1; i >= 0; i--) {
    convert[s[i].substr(0, s[i].find(':'))] = i;
  }

  int dp[50] = {};
  for (int i = M - 1; i >= 0; i--) {
    string ss = s[i].substr(s[i].find(':') + 2);
    vector<string> splits;
    string curr;
    for (int j = 0; j <= ss.size(); j++) {
      if (j == ss.size() || ss[j] == ' ')
        splits.push_back(curr), curr = "";
      else
        curr += ss[j];
    }
    for (auto &t : splits) {
      if (t[0] == '[') {
        int mask = 0;
        for (int j = 0; j < buff.size(); j++) {
          if (t.find(buff[j]) != string::npos) {
            mask |= 1 << j;
          }
        }
        toto[i].emplace_back(0, mask);
        dp[i] = min(sum + 1, dp[i] + 1);
      } else {
        toto[i].emplace_back(1, convert[t]);
        dp[i] = min(sum + 1, dp[i] + dp[convert[t]]);
      }
    }
  }

  if (dp[0] != sum) {
    cout << 0 << endl;
  } else {
    dfs(0);

    dp2[0][0][0][0] = 1;
    for (int bit : order) {
      memset(dp3, 0, sizeof(dp3));
      for (int i = 0; i <= 50; i++) {
        for (int j = 0; j <= 50; j++) {
          for (int k = 0; k <= 50; k++) {
            for (int l = 0; l <= 50; l++) {
              if ((bit >> 0) & 1)
                (dp3[i + 1][j][k][l] += dp2[i][j][k][l]) %= mod;
              if ((bit >> 1) & 1)
                (dp3[i][j + 1][k][l] += dp2[i][j][k][l]) %= mod;
              if ((bit >> 2) & 1)
                (dp3[i][j][k + 1][l] += dp2[i][j][k][l]) %= mod;
              if ((bit >> 3) & 1)
                (dp3[i][j][k][l + 1] += dp2[i][j][k][l]) %= mod;
            }
          }
        }
      }
      swap(dp2, dp3);
    }
    cout << dp2[Na][Nt][Ng][Nc] << endl;
  }
}