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

#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
int dp[2][32][32][32];
vector<int> r[62];
int to[62];
int p[30];
int q[30];
int n, m, s;
int calc(int a, int b, int c, int d) {
  // printf("%d %d %d %d\\n",a,b,c,d);
  if (~dp[a][b][c][d])
    return dp[a][b][c][d];
  if (b == c) {
    if (a == 0) {
      if (d == p[b])
        return dp[a][b][c][d] = 1;
      else
        return dp[a][b][c][d] = 0;
    } else {
      if (d == q[b])
        return dp[a][b][c][d] = 1;
      else
        return dp[a][b][c][d] = 0;
    }
  }
  int len = c - b + 1;
  if (len <= 0) {
    if (!a)
      len += n;
    else
      len += m;
  }
  for (int v = 0; v < s; v++) {
    if (to[v] != d)
      continue;
    int dp3[32][32];
    for (int i = 0; i < 32; i++)
      for (int j = 0; j < 32; j++)
        dp3[i][j] = 0;
    dp3[0][0] = 1;
    //	if(a==1&&b==1&&c==0&&d==0&&v==2)printf("%d %d\\n",(int)r[v].size(),len);
    for (int i = 0; i < r[v].size(); i++)
      for (int j = 0; j < len; j++) {
        if (!dp3[i][j])
          continue;
        //	if(a==1&&b==1&&c==0&&d==0&&v==2)printf("%d %d\\n",i,j);
        for (int k = j; k < len; k++) {
          if (j == 0 && k == len - 1)
            continue;
          int L = b + j;
          if (!a)
            L %= n;
          else
            L %= m;
          int R = b + k;
          if (!a)
            R %= n;
          else
            R %= m;
          if (calc(a, L, R, r[v][i]))
            dp3[i + 1][k + 1] = 1;
        }
      }
    if (dp3[r[v].size()][len])
      return dp[a][b][c][d] = 1;
  }
  return dp[a][b][c][d] = 0;
}
int dpv[2][32][32];
int dp2[32][32];
int main() {
  int a, b, c;
  while (scanf("%d%d%d", &a, &b, &c), a) {
    n = a;
    m = b;
    s = c;
    for (int i = 0; i < a; i++)
      scanf("%d", p + i);
    for (int i = 0; i < a; i++)
      p[i]--;
    for (int i = 0; i < b; i++)
      scanf("%d", q + i);
    for (int i = 0; i < b; i++)
      q[i]--;
    for (int i = 0; i < 62; i++)
      r[i].clear();
    for (int i = 0; i < c; i++) {
      int d;
      scanf("%d", &d);
      for (int j = 0; j < d; j++) {
        int e;
        scanf("%d", &e);
        e--;
        r[i].push_back(e);
      }
      scanf("%d", to + i);
      to[i]--;
    }

    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 32; j++)
        for (int k = 0; k < 32; k++)
          for (int l = 0; l < 32; l++)
            dp[i][j][k][l] = -1;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < a; j++)
        for (int k = 0; k < 30; k++) {
          //		printf("%d %d %d %d\\n",0,i,j,k);
          calc(0, i, j, k);
          //		if(dp[0][i][j][k])printf("%d %d %d %d\\n",0,i,j,k);
        }
    for (int i = 0; i < b; i++)
      for (int j = 0; j < b; j++)
        for (int k = 0; k < 30; k++) {
          //	printf("%d %d %d %d\\n",1,i,j,k);
          calc(1, i, j, k);
          //	if(dp[1][i][j][k])printf("%d %d %d %d\\n",1,i,j,k);
        }
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 32; j++)
        for (int k = 0; k < 32; k++) {
          dpv[i][j][k] = 0;
        }
    for (int i = 0; i < a; i++)
      for (int j = 0; j < a; j++)
        for (int k = 0; k < 30; k++)
          if (dp[0][i][j][k])
            dpv[0][i][j] += (1 << k);
    for (int i = 0; i < b; i++)
      for (int j = 0; j < b; j++)
        for (int k = 0; k < 30; k++)
          if (dp[1][i][j][k])
            dpv[1][i][j] += (1 << k);

    int ret = -1;
    for (int i = 0; i < n; i++) {
      for (int v = 0; v < m; v++) {
        for (int j = 0; j < 32; j++)
          for (int k = 0; k < 32; k++)
            dp2[j][k] = -999999999;
        dp2[0][0] = 0;
        for (int j = 0; j < n; j++) {
          for (int k = 0; k < m; k++) {
            for (int f = j; f < n; f++)
              for (int g = k; g < m; g++) {
                if (dpv[0][(i + j) % n][(i + f) % n] &
                    dpv[1][(v + k) % m][(v + g) % m])
                  dp2[f + 1][g + 1] = max(dp2[f + 1][g + 1], dp2[j][k] + 1);
              }
          }
        }
        ret = max(ret, dp2[n][m]);
      }
    }
    printf("%d\\n", ret);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
int dp[2][32][32][32];
vector<int> r[62];
int to[62];
int p[30];
int q[30];
int n, m, s;
int calc(int a, int b, int c, int d) {
  // printf("%d %d %d %d\\n",a,b,c,d);
  if (~dp[a][b][c][d])
    return dp[a][b][c][d];
  if (b == c) {
    if (a == 0) {
      if (d == p[b])
        return dp[a][b][c][d] = 1;
      else
        return dp[a][b][c][d] = 0;
    } else {
      if (d == q[b])
        return dp[a][b][c][d] = 1;
      else
        return dp[a][b][c][d] = 0;
    }
  }
  int len = c - b + 1;
  if (len <= 0) {
    if (!a)
      len += n;
    else
      len += m;
  }
  for (int v = 0; v < s; v++) {
    if (to[v] != d)
      continue;
    for (int w = 0; w < 1; w++) {

      bool ok = true;
      int dp3[32][32];
      for (int i = 0; i < 32; i++)
        for (int j = 0; j < 32; j++)
          dp3[i][j] = 0;
      dp3[0][0] = 1;
      //	if(a==1&&b==1&&c==0&&d==0&&v==2)printf("%d
      //%d\\n",(int)r[v].size(),len);
      for (int i = 0; i < r[v].size(); i++)
        for (int j = 0; j < len; j++) {
          if (!dp3[i][j])
            continue;
          //	if(a==1&&b==1&&c==0&&d==0&&v==2)printf("%d %d\\n",i,j);
          for (int k = j; k < len; k++) {
            if (j == 0 && k == len - 1)
              continue;
            int L = b + j;
            if (!a)
              L %= n;
            else
              L %= m;
            int R = b + k;
            if (!a)
              R %= n;
            else
              R %= m;
            if (calc(a, L, R, r[v][(i + w) % r[v].size()]))
              dp3[i + 1][k + 1] = 1;
          }
        }
      if (dp3[r[v].size()][len])
        return dp[a][b][c][d] = 1;
    }
  }
  return dp[a][b][c][d] = 0;
}
int dp2[32][32];
int main() {
  int a, b, c;
  while (scanf("%d%d%d", &a, &b, &c), a) {
    n = a;
    m = b;
    s = c;
    for (int i = 0; i < a; i++)
      scanf("%d", p + i);
    for (int i = 0; i < a; i++)
      p[i]--;
    for (int i = 0; i < b; i++)
      scanf("%d", q + i);
    for (int i = 0; i < b; i++)
      q[i]--;
    for (int i = 0; i < 62; i++)
      r[i].clear();
    for (int i = 0; i < c; i++) {
      int d;
      scanf("%d", &d);
      for (int j = 0; j < d; j++) {
        int e;
        scanf("%d", &e);
        e--;
        r[i].push_back(e);
      }
      scanf("%d", to + i);
      to[i]--;
    }

    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 32; j++)
        for (int k = 0; k < 32; k++)
          for (int l = 0; l < 32; l++)
            dp[i][j][k][l] = -1;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < a; j++)
        for (int k = 0; k < 30; k++) {
          //		printf("%d %d %d %d\\n",0,i,j,k);
          calc(0, i, j, k);
          //		if(dp[0][i][j][k])printf("%d %d %d %d\\n",0,i,j,k);
        }
    for (int i = 0; i < b; i++)
      for (int j = 0; j < b; j++)
        for (int k = 0; k < 30; k++) {
          //	printf("%d %d %d %d\\n",1,i,j,k);
          calc(1, i, j, k);
          //	if(dp[1][i][j][k])printf("%d %d %d %d\\n",1,i,j,k);
        }

    int ret = -1;
    for (int i = 0; i < n; i++) {
      for (int v = 0; v < m; v++) {
        for (int j = 0; j < 32; j++)
          for (int k = 0; k < 32; k++)
            dp2[j][k] = -999999999;
        dp2[0][0] = 0;
        for (int j = 0; j < n; j++) {
          for (int k = 0; k < m; k++) {
            for (int l = 0; l < 30; l++) {
              vector<int> L;
              vector<int> R;
              for (int f = j; f < n; f++) {
                if (dp[0][(i + j) % n][(i + f) % n][l])
                  L.push_back(f);
              }
              for (int f = k; f < m; f++) {
                if (dp[1][(v + k) % m][(v + f) % m][l])
                  R.push_back(f);
              }
              for (int f = 0; f < L.size(); f++)
                for (int g = 0; g < R.size(); g++)
                  dp2[L[f] + 1][R[g] + 1] =
                      max(dp2[L[f] + 1][R[g] + 1], dp2[j][k] + 1);
            }
          }
        }
        ret = max(ret, dp2[n][m]);
      }
    }
    printf("%d\\n", ret);
  }
}