Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func init() {
	sc.Split(bufio.ScanWords)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func lcs(a, b string) int {
	lenA := len(a)
	lenB := len(b)
	dp := make([][]int, lenA+1)
	for i := range dp {
		dp[i] = make([]int, lenB+1)
	}

	for i := 1; i <= lenA; i++ {
		for j := 1; j <= lenB; j++ {
			if a[i-1] == b[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else {
				dp[i][j] = max(dp[i][j-1], dp[i-1][j])
			}
		}
	}
	return dp[lenA][lenB]
}

func main() {
	n := scanInt()
	w := bufio.NewWriter(os.Stdout)
	for i := 0; i < n; i++ {
		a := scanString()
		b := scanString()
		fmt.Fprintln(w, lcs(a, b))
	}
	w.Flush()
}

C++: #include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

int dp[1010][1010];

int main(){
    int q; cin >> q;
    rep(i,q){
        string x,y; cin >> x >> y;
        for(int i = 0; i < x.size(); i++){
            for(int j = 0; j < y.size(); j++){
                if(x[i]==y[j]) dp[i+1][j+1] = dp[i][j] + 1;
                else dp[i+1][j+1] = max(dp[i+1][j],dp[i][j+1]);
            }
        }
        cout << dp[x.size()][y.size()] << endl;
    } 
    return 0;
}

C++: #include <iostream>
#include <string>

/*int LCS(std::string str1, std::string str2, int i, int j){
  if(str1[i] == str2[j]){
    return 1;
  }
  else{
    return 0;
  }
 }
*/

int max(int a, int b, int c){
  int m = a;
  if(b > m){
    m = b;
  }
  if(c > m){
    m = c;
  }
  return m;
}

int main(){
  int q;
  std::cin >> q;
  //int ans[q];
  std::string str1, str2;
  for(int z=0; z<q; z++){
    std::cin >> str1 >> str2;
    int l1 = str1.size();
    int l2 = str2.size();
    int DP[l1+1][l2+1];

    for(int i=0; i<=l1; i++){
      DP[i][0] = 0;
    }
    for(int j=0; j<=l2; j++){
      DP[0][j] = 0;
    }

    for(int i=1; i<=l1; i++){
      for(int j=1; j<=l2; j++){
	if(str1[i-1] == str2[j-1]){
	  DP[i][j] = max(DP[i-1][j], DP[i][j-1], DP[i-1][j-1] + 1);
	}
	else{
	  DP[i][j] = max(DP[i-1][j], DP[i][j-1], DP[i-1][j-1]);
	}
      }
    }
    //ans[z] = DP[l1][l2];
    std::cout << DP[l1][l2] << std::endl;
  }

  /*for(int z=0; z<q; z++){
    std::cout << ans[z] << std::endl;
    }*/
  return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
#define INF 100000000000
const int MOD = 1000000009

//マクロ
#define FOR(i, a, b) for(int i = (a); i < (b), i++)
#define REP(i, n) FOR(i, 0, n);
#define ALL(a) (a).begin(),(a).end()

// 最長共通部分列問題
// 入力
// S T

// dp[i + 1][j + 1] := Sのi文字目までと、Tのj文字目までのLCSの長さ
// 計算量 O(|S||T|)

int main(){

    //入力
    int n; cin >> n;
    for(int roop = 0; roop < n; roop++){
        string S, T; cin >> S >> T;
        vector<vector<int> > dp(S.size() + 1, vector<int> (T.size() + 1, INF));

        //dp初期条件
        dp[0][0] = 0;

        //dp
        for(int i = 0; i < S.size(); i++){
            for(int j = 0; j < T.size(); j++){
                if(S[i] == T[j]) dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j]);
                dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i + 1][j]);
                dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j + 1]);
            }
        }

        cout << dp[S.size()][T.size()];
        return 0;
    }
}

C++: #include <iostream>

using namespace std;

int lcs(string X, string Y) {
  int memo[1010][1010];
  // 初期化
  for (int i = 0; i < X.size(); i++) {
    memo[i][0] = 0;
  }
  for (int i = 0; i < Y.size(); i++) {
    memo[0][i] = 0;
  }
  int maxl = 0;
  int k = 0;
  for (int i = 0; i < X.size(); i++) {
    for (int j = 0; j < Y.size(); j++) {
      if (i <= 0 || j <= 0) {
        if (X[i] == Y[j]) {
          memo[i][j] = 1;
        } else {
          memo[i][j] = 0;
        }
      }
      else if (X[i] == Y[j]) {
        memo[i][j] = memo[i-1][j-1] + 1;
      } else {
        memo[i][j] = max(memo[i-1][j], memo[i][j-1]);
      }
      //cout << i << "," << j << "," << memo[i][j] << endl;
      maxl = max(maxl, memo[i][j]);
    }
  }
  return maxl;
}

int main() {
  int q; cin >> q;
  for (int i = 0; i < q; i++) {
    string X, Y; cin >> X >> Y;
    cout << lcs(X, Y) << endl;
  }
}

C++: #include <bits/stdc++.h>
using namespace std;
int main(){
    int q;
    cin >> q;
    string s1, s2;
    for(int i = 0; i < q; i++){
        cin >> s1 >> s2;
        int l1 = s1.size() + 1, l2 = s2.size() + 1, maxl = 0;
        int dp[1000 + 1][1000 + 1];
        for(int j = 0; j < l1; j++) dp[j][0] = 0;
        for(int k = 0; k < l2; k++) dp[0][k] = 0;
        for(int j = 1; j < l1; j++){
            for(int k = 1; k < l2; k++){
                if(s1[j - 1] == s2[k - 1]) dp[j][k] = dp[j - 1][k - 1] + 1;
                else dp[j][k] = max(dp[j - 1][k], dp[j][k - 1]);
                maxl = max(maxl, dp[j][k]);
            }
        }
        cout << maxl << endl;
    }
}

C++: #include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int cal(string na,string me){
  int l=na.size();
  int r=me.size();
  int h[1005][1005];
  for(int i=0;i<l;i++){
    for(int j=0;j<r;j++){
      h[i][j]=0;
    }
  }

  int ans=0;
  for(int i=1;i<=l;i++){
    for(int j=1;j<=r;j++){

      if(na[i-1]==me[j-1]) h[i][j]=h[i-1][j-1]+1;
      else h[i][j]=max(h[i][j-1],h[i-1][j]);

      ans=max(ans,h[i][j]);
    }
  }
  return ans;
}

int main(){
  int n,ans=0;
  cin>>n;

  string na,me;
  for(int i=0;i<n;i++){
    cin>>na>>me;
    ans=cal(na,me);
    cout<<ans<<endl;
  }

  return 0;
}

C++: #include <iostream>
#include <string>
#include <algorithm>


using namespace std;
const int MaxStringSize = 1000;
const int NullMemo = -1;

int calc_LCS(string str1, string str2) {
  // Memo[n][m] は str1.sub(0, n) と str2.sub(0, m)のLCSをmemoする。
  int memoLCS[str1.size() + 1][str2.size() + 1];

  for(int i = 0; i <= str1.size(); i++) {
    memoLCS[i][0] = 0;
  }
  for(int i = 0; i <= str2.size(); i++) {
    memoLCS[0][i] = 0;
  }

  for(int i = 1; i <= str1.size(); i++) {
    for(int j = 1; j <= str2.size(); j++) {
      if(str1[i - 1] == str2[j - 1]) {
        memoLCS[i][j] = memoLCS[i - 1][j - 1] + 1;
      } else {
        memoLCS[i][j] = max(memoLCS[i][j - 1], memoLCS[i - 1][j]);
      }
    }
  }

  return memoLCS[str1.size()][str2.size()];
}

int main() {
  int datasets_num;
  string str1;
  string str2;

  cin >> datasets_num;

  for(int i = 0; i < datasets_num; i++) {
    cin >> str1 >> str2;

    cout << calc_LCS(str1, str2) << endl;
  }
}

C++: #include<iostream>
#include<cstring>
#define LcsMaxLen 1005
using namespace std;
char sf[LcsMaxLen];
char ss[LcsMaxLen];
int mark[LcsMaxLen][LcsMaxLen]={0};
int LcsLen( int sfi,int ssi ){
	if(sfi<0||ssi<0)
		return 0;
	if(mark[sfi][ssi])return mark[sfi][ssi];
	if(sf[sfi]==ss[ssi]){
		mark[sfi][ssi] = LcsLen(sfi-1,ssi-1)+1;
		return mark[sfi][ssi];
	}
	else {
		mark[sfi][ssi] = max(LcsLen(sfi,ssi-1),LcsLen(sfi-1,ssi));
		return mark[sfi][ssi];
	}
} 
int main(){
	int n,len;
	cin>>n;
	while(n--){
	cin>>sf>>ss;
	len = max(strlen(sf),strlen(ss));
	for(int i = 0;i<len;++i)
		for(int j = 0;j<len;++j)
			mark[i][j]=0;
	cout<<LcsLen(strlen(sf)-1,strlen(ss)-1)<<endl;
	} 
	return 0;
}

C++: #include <iostream>

using namespace std;

int ans(string a, string b) {
  int n = a.size();
  int m = b.size();
  int memo[n+1][m+1];
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= m; j++) {
      memo[i][j] = 0;
    }
  }

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      int res = max(memo[i-1][j], memo[i][j-1]);
      if (a[i] == b[j]) {
        res = max(res, memo[i-1][j-1] + 1);
      } else {
        res = max(res, memo[i-1][j-1]);
      }
      memo[i][j] = res;
    }
  }
  
  return memo[n][m];
}

int main() {
  int q;
  cin >> q;

  for (int i = 0; i < q; i++) {
    string a, b;
    cin >> a >> b;
    
    cout << ans(a, b) << endl;
  }

  return 0;
}