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

#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define LL long long

string X, Y;
int q, Z;
int dp[1001][1001] = {};

int main() {
  cin >> q;
  for (int ds = 0; ds < q; ds++) {
    cin >> X >> Y;
    int xs = X.size(), ys = Y.size();
    for (int i = 0; i < xs; i++) {
      for (int j = 0; j < ys; j++) {
        int tmp = 0;
        if (X[i] == Y[j]) {
          if (i * j == 0)
            dp[i][j] = 1;
          else
            dp[i][j] = dp[i - 1][j - 1] + 1;
        } else {
          if (i + j == 0)
            dp[0][0] = 0;
          else if (i == 0)
            dp[0][j] = dp[0][j - 1];
          else if (j == 0)
            dp[i][0] = dp[i - 1][0];
          else
            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
        }
      }
    }
    cout << dp[xs - 1][ys - 1] << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<char, vector<int>> alx, aly; // x,y
int memo[1010][1010];
string x, y, q;
int lcs(int xn, int yn) { // yn文字目以降でX[xn]と同じやつを探す
  if (memo[xn][yn] != -1)
    return memo[xn][yn];
  int ans = 0;
  /*
for(int i=xn; i<x.size();i++){
  for(int j=yn; j<y.size(); j++){
      if(alx[x[i]]==aly[y[j]]){
          ans=max(ans,lcs(i+1,j+1)+1);
      }
  }
}
  */
  for (int i = xn; i < x.size(); i++) {
    for (int j = 0; j < aly[x[i]].size(); j++) {
      if (aly[x[i]][j] < yn)
        continue;
      ans = max(ans, lcs(i + 1, aly[x[i]][j] + 1) + 1);
      break;
    }
  }
  return memo[xn][yn] = ans;
}

int main() {
  int q;
  cin >> q;
  for (int ds = 0; ds < q; ds++) {

    cin >> x >> y;
    for (int i = 0; i <= x.size(); i++) {
      for (int j = 0; j <= y.size(); j++) {
        memo[i][j] = -1;
      }
    }

    alx.clear();
    aly.clear();

    for (int i = 0; i < x.size(); i++)
      alx[x[i]].push_back(i);
    for (int i = 0; i < y.size(); i++)
      aly[y[i]].push_back(i);

    // memset(memo, -1, sizeof(memo));

    cout << lcs(0, 0) << endl;
  }
  return 0;
}

/*
int memo[1010][1010];
string x,y,q;
int lcs(int xn,int yn){//Y[yn]とX[xn]を比較
    if(memo[xn][yn]!=-1)return memo[xn][yn];
        else if(xn==0 || yn==0)return 0;
        else if(x[xn]==y[yn])return memo[xn][yn] = lcs(xn-1,yn-1)+1;
        else  return memo[xn][yn] = max(lcs(xn,yn-1),lcs(xn-1,yn));
}


int main(){
    int q;
    cin >> q;
    for(int ds=0; ds<q; ds++){

        cin >> x >> y;
        for(int i=0; i<=x.size(); i++){
            for(int j=0; j<=y.size(); j++)memo[i][j]=-1;
        }
        //memset(memo, -1, sizeof(memo));

        cout << max(lcs(x.size(),y.size()),0) << endl;

    }
    return 0;
}*/

/*

#include<algorithm>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
int n,memo[50]={};

int fib(int n){
        if(memo[n]!=0)return memo[n];
        return memo[n]=fib(n-1)+fib(n-2);
}


int main(){

        cin >> n;
        memo[0]=1;
        memo[1]=1;
        for(int i=2; i<=n; i++)
                memo[i]=memo[i-1]+memo[i-2];
        cout << memo[n] << endl;
        return 0;
}
*/

/*
#include<queue>
using namespace std;
int n,A[2000],q;//A:0origin
int memo[2000][2000];

bool solve(int i,int m){//i番目以降のAを使ってmを作る
        if(m==0) return true;//０はどんなときも作れる
        if(i==n) return false;//すべて使ってもつくれない
        //すでにやってるときメモを返す
        if(memo[i][m]!=0){
                if(memo[i][m]==-1)return false;
                else return true;
        }
        //solve(i,m)  A[i]を使う solve(i+1,m-A[i]) || 使わない　solve(i+1,m)
        bool X=false;
        if(m-A[i]>=0 && solve(i+1,m-A[i])) X=true;
        else if(solve(i+1,m)) X = true;

        if(X)memo[i][m]=1;
        else memo[i][m]=-1;

         return X;

}

int main(){

        cin >> n;

        for(int i=0; i<n; i++) cin >> A[i];


        cin >> q;

        for(int i=0; i<q; i++){
                int m;
                cin >> m;
                for(int k=0; k<n; k++){
                        for(int j=0; j<n; j++) memo[k][j]=0;
                }

                if(solve(0,m))cout << "yes" << endl;
                else cout << "no" << endl;
        }

        return 0;
}

*/

/*
        bool dp[2000][2000];
        bool memo[2000][2000];//[順番][m-これまでの総和]

        bool solve(int now,int least){
                if(now == n) return false;//now>nならfalse
                else if(least == 0)return true;//least==0 >> true
                else if(memo[now][least])return dp[now][least];//already diside
   >> そのまま出来上がってるのを返す else if(solve(now+1,least))dp[now][least] =
   true;//A[now]をとらない >> solve(now++,least) else if(least-A[now] > 0 &&
   solve(now++,least-A[now]))dp[now][least] = true;//A[now]をとる
   (least-A[now]>0 only)>> solve(now++,least-A[now]) else dp[now][least] =
   false; memo[now][least] = true; return dp[now][least];
        }
        */