Go: package main

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

func max(x, y int) int {
	if x < y {
		return y
	} else {
		return x
	}
}

/*********************************************************************
長さmの列X_(m)と長さnの列Y_(n)の最長共通部分列LCSは、
	(1)X[m] == Y[n]ならば、X_(m-1)とY_(n-1)のLCSにX[m]を繋げたもの
	(2)X[m] != Y[n]ならば、X_(m-1)とY_(n)のLCSもしくはX_(m)とY_(n-1)のLCS
	のいずれかのうち長い方

c[m+1][n+1]：c[i][j]にX_(i)とY_(j)のLCSの長さを格納する二次元配列
*********************************************************************/

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())
	for i := 0; i < n; i++ {
		scanner.Scan()
		s1 := scanner.Text()
		scanner.Scan()
		s2 := scanner.Text()
		s1, s2 = s1 + " ", s2 + " "
		c := make([][]int, len(s1))
		for i := range c {
			c[i] = make([]int, len(s2))
		}

		LCS := 0

		for i := 1; i < len(s1); i++ {
			for j := 1; j < len(s2); j++ {
				if s1[i] == s2[j] {
					c[i][j] = c[i-1][j-1] + 1
				} else {
					c[i][j] = max(c[i-1][j], c[i][j-1])
				}
				LCS = max(LCS, c[i][j])
			}
		}
		fmt.Println(LCS)
	}
}

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

const int MAX_N = 1000, MAX_M = 1000;
int dp[MAX_N + 1][MAX_M + 1];

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

	for (int i = 0;i < q;i++) {
		string x, y; cin >> x >> y;

		for (int i = 0;i <= x.size();i++)
			for (int j = 0;j <= y.size();j++) dp[i][j] = 0;

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

C++: /*
 * ALDS1_10_C.cpp
 *
 *  Created on: May 5, 2018
 *      Author: 13743
 */

#include<cstdio>
#include<cstring>
#include<algorithm>

int dp[1001][1001];

int lcm(char* X, char* Y, int nx, int ny) {
	dp[1][1] = (X[0] == Y[0]);
	for(int i=1; i<=nx; i++) {
		for(int j=1; j<=ny; j++) {
			dp[i][j] = (X[i-1]==Y[j-1]) + dp[i-1][j-1];
			dp[i][j] = std::max(dp[i-1][j], dp[i][j]);
			dp[i][j] = std::max(dp[i][j-1], dp[i][j]);
		}
	}
	return dp[nx][ny];
}

int main() {
	int q;
	scanf("%d", &q);
	char X[1001];
	char Y[1001];
	while(q--) {
		scanf("%s", X);
		scanf("%s", Y);
		int nx = (int)strlen(X);
		int ny = (int)strlen(Y);
		printf("%d\n", lcm(X, Y, nx, ny));
	}
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
#include <numeric>
#include <array>
#include <cmath>
#include <memory>
using namespace std;
//変数デバッグ
#define DEB(variable) cout << #variable << '=' << variable << endl

//for簡易表記(引数ミス防止)
#define FOR(LoopVariable,numberOFbegin,numberOFend) for (int LoopVariable = (numberOFbegin); (LoopVariable) <= (numberOFend); (LoopVariable)++)
#define DEFOR(LoopVariable,numberOFbegin,numberOFend) for (int LoopVariable = (numberOFbegin)-1; (LoopVariable) >= (numberOFend); (LoopVariable)--)
#define REP(LoopVariable,numberOFend) for(int LoopVariable = 0;(LoopVariable)<(numberOFend);LoopVariable++)

constexpr long long int linf = numeric_limits<long long int>::max()-5;
constexpr int inf= numeric_limits<int>::max()-5;
constexpr long long int mod = 1000000007;


void solve(){
    string s, t;
    cin >> s >> t;
    vector<vector<int>> grid(s.size()+1, vector<int>(t.size()+1));

    grid[0][0] = 0;
    FOR(i,1,s.size()){
        grid[i][0] = 0;
    }
    FOR(i,1,t.size()){
        grid[0][i] = 0;
    }

    FOR(i,1,s.size()){
        FOR(j,1,t.size()){
            if(s[i-1]==t[j-1]){
                grid[i][j] = grid[i - 1][j - 1] + 1;
            }else{
                grid[i][j] = max(grid[i][j - 1], grid[i - 1][j]);
            }
        }

    }
    cout << grid[s.size()][t.size()] << endl;

}



int main(){

    int n;
    cin >> n;
    REP(i,n){
        solve();
    }

    return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
typedef pair<ll, ll> Pll;
typedef vector<int> Vi;
typedef tuple<int, int, int> T;
#define FOR(i,s,x) for(int i=s;i<(int)(x);i++)
#define REP(i,x) FOR(i,0,x)
#define ALL(c) c.begin(), c.end()
#define DUMP( x ) cerr << #x << " = " << ( x ) << endl

int dp[1024][1024];

int main() {
  // use scanf in CodeForces!
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N;
  cin >> N;
  REP(q, N) {
    memset(dp, 0, sizeof(dp));
    string X, Y;
    cin >> X >> Y;
    int LX = X.size(), LY = Y.size();
    REP(i, LX) REP(j, LY) {
      if (X[i] == Y[j]) {
	dp[i+1][j+1] = max(dp[i][j] + 1, max(dp[i+1][j], dp[i][j+1]));
      } else {
	dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]);
      }
    }
    cout << dp[LX][LY] << endl;
  }
  return 0;
}

C++: #include <bits/stdc++.h>

#define rep(i, a, b) for (int i = a; i < (int)(b); ++i)
#define rrep(i, a, b) for (int i = b - 1; i >= (int)(a); --i)

using namespace std;

using ll = long long;
using vi = vector<int>;
using vii = vector<vi>;
using vll = vector<ll>;

int calc(vii& dp, const string& x, const string& y) {
    int m = x.size(), n = y.size();

    rep(i, 0, m) {
        rep(j, 0, n) {
            if (x[i] == y[j]) {
                dp[i + 1][j + 1] = dp[i][j] + 1;
            } else {
                dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j]);
            }
        }
    }
    return dp[m][n];
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int q;
    cin >> q;

    rep(i, 0, q) {
        string x, y;
        cin >> x >> y;

        vii dp(x.size() + 1, vi(y.size() + 1, 0));
        cout << calc(dp, x, y) << endl;
    }

    return 0;
}

C++: #include <iostream>
#include <string>
#include <algorithm>
using namespace std;
static const int n=1000;

int lcs(string x,string y){
  int c[n+1][n+1];
  int m=x.size();
  int n=y.size();
  int maxl=0;
  x=' '+x;
  y=' '+y;
  for(int i=1;i<=m;i++)c[i][0]=0;
  for(int i=1;i<=n;i++)c[0][i]=0;

  for(int i=1;i<=m;i++){
    for(int j=1;j<=n;j++){
      if(x[i]==y[j]){
	c[i][j]=c[i-1][j-1]+1;
      }else {
	c[i][j]=max(c[i-1][j],c[i][j-1]);
      }
      maxl=max(maxl,c[i][j]);
    }
  }
  return maxl;
}

int main(){
  string s1,s2;
  int n;
  cin>>n;
  for(int i=0;i<n;i++){
    cin>>s1>>s2;
    cout<<lcs(s1,s2)<<endl;
  }
  return 0;
}

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

#define rep(i, m) for (int i = 0; i < m; i++)
#define REP(i, n, m) for (int i = n; i < m; i++)

using namespace std;

int q;
string s, t;
int dp[151][151];

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cin >> q;
	rep(k, q) {
		cin >> s >> t;
		rep(i, 101) rep(j, 101) dp[i][j] = 0;
		rep(i, s.size()) {
			rep(j, t.size()) {
				if (s[i] == t[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[s.size()][t.size()] << "\n";
	}
	return 0;
}

C++: #include <iostream>
#include <string>
using namespace std;
int A[1005][1005]={};

int main() {
  int i,j,k,q;
  cin >> q;
  string a,b;
  for(i=0;i<q;i++) {
    cin  >> a >> b;
    int al = a.size();
    int bl = b.size();
    for(j=1;j<=al;j++) {
      for(k=1;k<=bl;k++) {
        if(a[j-1]==b[k-1]) {
          A[j][k]=A[j-1][k-1]+1;
        } else {
          A[j][k]=max(A[j][k-1],A[j-1][k]);
        }
      }
    }
    cout << A[al][bl] << endl;
  }
  return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
const int DP_SIZE = 1010;

int dp[DP_SIZE][DP_SIZE];

int main(){
	int N;
	cin >> N;
	
	for(int n=0; n<N; n++){
		for(int i=0; i<DP_SIZE; i++) for(int j=0; j<DP_SIZE; j++) dp[i][j] = 0;
		string S, T;
		cin >> S >> T;
		for(int i=0; i<(int)S.size(); i++){
			for(int j=0; j<(int)T.size(); j++){
				if(S[i] == T[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[S.size()][T.size()] << endl;
	}
	
	return 0;
}