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

#include "bits/stdc++.h"
using namespace std;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2437&lang=jp
typedef long long ll;
#define INF 1 << 30
const int mod = 1e9 + 7;
int dp[55][55][55][55];
int Sum;
int Na, Nt, Ng, Nc;
map<string, int> mp;
vector<vector<string>> ms;

vector<string> split(const string &str, char c) {
  vector<string> ret;
  stringstream ss(str);
  string item;
  while (getline(ss, item, c)) {
    if (!item.empty())
      ret.push_back(item);
  }
  return ret;
}

void decryp(const string &key, vector<string> &dec, int &_sum) {
  int len = (int)ms[mp[key]].size();
  for (int i = 1; i < len; i++) {
    if (ms[mp[key]][i][0] == '[') {
      dec.push_back(ms[mp[key]][i]);
      _sum++;
      if (_sum > Sum)
        return;
    } else {
      decryp(ms[mp[key]][i], dec, _sum);
      if (_sum > Sum)
        return;
    }
  }
  return;
}
int solve(int na, int nt, int ng, int nc, int inc, const vector<string> &dec) {
  if (inc == Sum) {

    return ((na == Na) && (nt == Nt) && (nc == Nc) && (ng == Ng));
  }
  int &res = dp[na][nt][ng][nc];
  if (res != -1)
    return res;
  res = 0;
  int L = dec[inc].length();
  for (int at = 1; at < L - 1; at++) {
    if (dec[inc][at] == 'A' && na < Na) {
      (res += solve(na + 1, nt, ng, nc, inc + 1, dec)) %= mod;
    } else if (dec[inc][at] == 'T' && nt < Nt) {
      (res += solve(na, nt + 1, ng, nc, inc + 1, dec)) %= mod;
    } else if (dec[inc][at] == 'G' && ng < Ng) {
      (res += solve(na, nt, ng + 1, nc, inc + 1, dec)) %= mod;
    } else if (dec[inc][at] == 'C' && nc < Nc) {
      (res += solve(na, nt, ng, nc + 1, inc + 1, dec)) %= mod;
    }
  }
  return res;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> Na >> Nt >> Ng >> Nc;
  int _m;
  cin >> _m;
  Sum = Na + Nt + Ng + Nc;
  cin.ignore();
  vector<string> ni(_m);
  string First;
  int idx = 0;
  for (int i = 0; i < _m; i++) {
    string temp;
    getline(cin, temp);
    ni[i] = temp;
    auto sp = split(ni[i], ' ');
    string f = sp[0].substr(0, sp[0].length() - 1);
    if (i == 0)
      First = f;
    mp[f] = idx;
    idx++;
    ms.push_back(sp);
  }

  vector<string> dec;
  int _sum = 0;
  decryp(First, dec, _sum);
  if (_sum != Sum) {
    cout << 0 << endl;
    return 0;
  }

  for (int i = 0; i < 55; i++)
    for (int j = 0; j < 55; j++)
      for (int k = 0; k < 55; k++)
        for (int l = 0; l < 55; l++) {
          dp[i][j][k][l] = -1;
        }
  cout << solve(0, 0, 0, 0, 0, dec) << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2437&lang=jp
typedef long long ll;
#define INF 1 << 30
const int mod = 1e9 + 7;
int dp[55][55][55][55];
int Sum;

vector<string> split(const string &str, char c) {
  vector<string> ret;
  stringstream ss(str);
  string item;
  while (getline(ss, item, c)) {
    if (!item.empty())
      ret.push_back(item);
  }
  return ret;
}

void decryp(const string &key, map<string, int> &mp, vector<vector<string>> &ms,
            int &_sum) {
  int len = (int)ms[mp[key]].size();
  for (int i = 1; i < len; i++) {
    if (ms[mp[key]][i][0] == '[') {

      for (int j = 50; j >= 0; j--) {
        for (int k = 50; k >= 0; k--) {
          for (int l = 50; l >= 0; l--) {
            for (int m = 50; m >= 0; m--) {
              if (dp[j][k][l][m] == 0)
                continue;
              string t = ms[mp[key]][i];
              int L = t.length();
              for (int at = 1; at < L - 1; at++) {
                if (t[at] == 'A') {
                  (dp[j + 1][k][l][m] += dp[j][k][l][m]) %= mod;
                } else if (t[at] == 'T') {
                  (dp[j][k + 1][l][m] += dp[j][k][l][m]) %= mod;
                } else if (t[at] == 'G') {
                  (dp[j][k][l + 1][m] += dp[j][k][l][m]) %= mod;
                } else if (t[at] == 'C') {
                  (dp[j][k][l][m + 1] += dp[j][k][l][m]) %= mod;
                }
              }
            }
          }
        }
      }

      _sum++;
      if (_sum > Sum)
        return;
    } else {
      decryp(ms[mp[key]][i], mp, ms, _sum);
      if (_sum > Sum)
        return;
    }
  }
  return;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int Na, Nt, Ng, Nc;
  cin >> Na >> Nt >> Ng >> Nc;
  int _m;
  cin >> _m;
  Sum = Na + Nt + Ng + Nc;
  cin.ignore();
  vector<string> ni(_m);
  // map<string, vector<string>> mp;
  map<string, int> mp;
  vector<vector<string>> ms;
  string First;
  int idx = 0;
  for (int i = 0; i < _m; i++) {
    string temp;
    getline(cin, temp);
    ni[i] = temp;
    auto sp = split(ni[i], ' ');
    string f = sp[0].substr(0, sp[0].length() - 1);
    if (i == 0)
      First = f;
    mp[f] = idx;
    idx++;
    ms.push_back(sp);
  }

  for (int i = 0; i < 55; i++)
    for (int j = 0; j < 55; j++)
      for (int k = 0; k < 55; k++)
        for (int l = 0; l < 55; l++) {
          dp[i][j][k][l] = 0;
        }
  dp[0][0][0][0] = 1;

  int _sum = 0;
  decryp(First, mp, ms, _sum);
  if (_sum != Sum) {
    cout << 0 << endl;
    return 0;
  }
  cout << dp[Na][Nt][Ng][Nc] << endl;
  return 0;
}