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<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int dp[1001][1001];

int main(){
	int i,n,j,k,la,lb;
	char a[1001],b[1001];
	scanf("%d",&n);
	while(n--){
		scanf("%s",a);
		scanf("%s",b);
		la = strlen(a);
		lb = strlen(b);
		for( i = 0; i < la; i++ ){
            for( j = 0; j < lb; j++ ){
                if( a[i] == b[j]){
                    dp[i+1][j+1] = dp[i][j] + 1;
                } else {
                    if( dp[i+1][j] >= dp[i][j+1] ){
                        dp[i+1][j+1] = dp[i+1][j];
                    } else dp[i+1][j+1] = dp[i][j+1];
                }
            }
		}
		printf("%d\n",dp[la][lb]);
	}
}

C++: #include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define spair(p) cout<<#p<<": "<<p.fi<<" "<<p.se<<endl
#define sar(a,n) cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl
#define svec(v) cout<<#v<<":";rep(pachico,v.size())cout<<" "<<v[pachico];cout<<endl
#define svecp(v) cout<<#v<<":";each(pachico,v)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl
#define sset(s) cout<<#s<<":";each(pachico,s)cout<<" "<<pachico;cout<<endl
#define smap(m) cout<<#m<<":";each(pachico,m)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl

using namespace std;

typedef pair<int,int> P;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<P> vp;
typedef vector<string> vs;

const int MAX_N = 100005;

const int MAX_SIZE = 52;

int LCS(const string& a, const string& b){
    int n = (int)a.size(), m = (int)b.size();
    vector<int> x(n), y(m);
    rep(i,n){
        x[i] = a[i]-'a';
        if(x[i] < 0){
            x[i] = a[i]-'A'+26;
        }
    }
    rep(i,m){
        y[i] = b[i]-'a';
        if(y[i] < 0){
            y[i] = b[i]-'A'+26;
        }
    }
    vector<vector<int> > vec(MAX_SIZE);
    for(int j = m-1; j >= 0; --j){
        vec[y[j]].push_back(j);
    }
    vector<int> xs(n+1, INF);
    xs[0] = -INF;
    rep(i,n){
        rep(j,(int)vec[x[i]].size()){
            *lower_bound(xs.begin(),xs.end(),vec[x[i]][j]) = vec[x[i]][j];
        }
    }
    return upper_bound(xs.begin(),xs.end(),INF-1) - xs.begin();
}


int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int q;
    cin >> q;
    rep(i,q){
        string a,b;
        cin >> a >> b;
        cout << LCS(a,b) << "\n";
    }
    return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define Rep(i, b, e) for(int (i) = (b); (i) < (e); ++(i))
#define Repr(i, b, e) for(int (i) = (b) - 1; (i) >= (e); --(i))
#define Print(x) cout << (x) << endl 
#define Min2(a, b) ((a) < (b)) ? (a) : (b)
#define Max2(a, b) ((a) > (b)) ? (a) : (b)

typedef long long ll;

using namespace std;

string X, Y;
int dp[1001][1001];

int max3(int a, int b, int c){
    return Max2(a, (Max2(b, c)));
}

int lcs(){
    int lenX = (int)X.length();
    int lenY = (int)Y.length();
    Rep(i, 0, lenX + 1) Rep(j, 0, lenY + 1) dp[i][j] = 0;
    Rep(i, 0, lenX){
        Rep(j, 0, lenY){
            dp[i + 1][j + 1] = max3(dp[i][j] + (X[i] == Y[j]), dp[i][j + 1], dp[i + 1][j]);
        }
    }
    return dp[lenX][lenY];
}

int main(){
    int q;
    cin >> q;
    Rep(i, 0, q){
        cin >> X >> Y;
        cout << lcs() << endl;
    }
    return 0;
}

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

using namespace std;
const int dx[]={1,0,-1,0,1,-1,-1,1,0};
const int dy[]={0,1,0,-1,1,1,-1,-1,0};
const int INF = 1e9+101;
const long long LINF = 1e18;
const double EPS = 1e-8;
#define pb push_back
#define mk make_pair
#define fr first
#define sc second
#define reps(i,j,k) for(ll i = (j); i < (k); ++i)
#define rep(i,j) reps(i,0,j)
#define all(a) (a).begin(),(a).end()
#define MOD 1000000007
typedef long long ll;
typedef pair<ll,ll> Pii;
typedef pair<Pii,int> P;
typedef vector<int> vi;
typedef vector<ll> vll;
template<class T>
ostream& operator<<(ostream &out, const vector<T> &v){
	out << "{";
	rep(i,v.size()){
		out << v[i] <<", ";
	}
	return out << "}" << endl;
}

int main() {
    int N;
    cin >> N;
    while(N--) {
        int dp[1024][1024] = {{}};
        string a,b;
        cin >> a >> b;
        int ans = 0;
        reps(i,1,a.size()+1){
            reps(j,1,b.size()+1) {
                dp[i][j] = max(dp[i-1][j],max(dp[i][j-1], dp[i-1][j-1]+(a[i-1]==b[j-1])));
                ans = max(ans, dp[i][j]);
            }
        }
        cout << dp[a.size()][b.size()] << endl;
    }
    return 0;  
}

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

int main(){
    int q;
    cin >> q;
    while(q-- > 0){
        string s, t;
        cin >> s >> t;
        s = " " + s; // padding
        t = " " + t; // padding
        int h = s.length(), w = t.length();
        vector<vector<int>> dp(h, vector<int>(w,0));
        for(int i = 1; i < h; i++){
            for(int j = 1; j < w; j++){
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                if(s[i] == t[j])    dp[i][j] = max(dp[i][j], dp[i-1][j-1]+1);
            }
        }
        cout << dp[h-1][w-1] << endl;
    }
    return 0;
}

C++: #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAX 1000

int main(){
  int n;
  cin>>n;
  string a,b;
  for(int i=0;i<n;i++){
    cin>>a>>b;
    int C[MAX+1][MAX+1]={0};
    for(int i=1;i<=a.size();i++){
      for(int j=1;j<=b.size();j++){
        if(a[i]==b[j]) C[i][j]=C[i-1][j-1]+1;
        else{
          C[i][j]=max(C[i-1][j],C[i][j-1]);
        }
      }
    }
    cout<<C[a.size()][b.size()]<<endl;
  }
  
}