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 <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <limits>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <functional>
#include <iomanip>

using namespace std;

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define eprintf(...) 42
#endif
using ll = long long;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
#define reps(i, S, E) for (ll i = (S); i <= (E); i++)
#define rep(i, N) reps(i, 0, N-1)
#define deps(i, E, S) for (ll i = (E); i >= (S); i--)
#define dep(i, N) deps(i, N-1, 0)
const ll INF = 1LL << 60;
const int INF_INT = 1 << 30;

template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true; }return false; }
template<class T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true; }return false; }
struct mll {
	static ll MOD;
	ll val;
	mll(ll v = 0) : val(v % MOD) { if (val < 0) val += MOD; }
	mll operator - () const { return -val; }
	mll operator + (const mll &b) const { return val + b.val; }
	mll operator - (const mll &b) const { return val - b.val; }
	mll operator * (const mll &b) const { return val * b.val; }
	mll operator / (const mll &b) const { return mll(*this) /= b; }
	mll operator + (ll b) const { return *this + mll(b); }
	mll operator - (ll b) const { return *this - mll(b); }
	mll operator * (ll b) const { return *this * mll(b); }
	friend mll operator + (ll a, const mll &b) { return b + a; }
	friend mll operator - (ll a, const mll &b) { return -b + a; }
	friend mll operator * (ll a, const mll &b) { return b * a; }
	mll &operator += (const mll &b) { val = (val + b.val) % MOD; return *this; }
	mll &operator -= (const mll &b) { val = (val + MOD - b.val) % MOD; return *this; }
	mll &operator *= (const mll &b) { val = (val*b.val) % MOD; return *this; }
	mll &operator /= (const mll &b) {
		ll c = b.val, d = MOD, u = 1, v = 0;
		while (d) {
			ll t = c / d;
			c -= t * d; swap(c, d);
			u -= t * v; swap(u, v);
		}
		val = val * u % MOD;
		if (val < 0) val += MOD;
		return *this;
	}
	mll &operator += (ll b) { return *this += mll(b); }
	mll &operator -= (ll b) { return *this -= mll(b); }
	mll &operator *= (ll b) { return *this *= mll(b); }
	mll &operator /= (ll b) { return *this /= mll(b); }
	bool operator == (const mll &b) { return val == b.val; }
	bool operator != (const mll &b) { return val != b.val; }
	bool operator == (ll b) { return *this == mll(b); }
	bool operator != (ll b) { return *this != mll(b); }
	friend bool operator == (ll a, const mll &b) { return mll(a) == b.val; }
	friend bool operator != (ll a, const mll &b) { return mll(a) != b.val; }
	friend ostream &operator << (ostream &os, const mll &a) { return os << a.val; }
	friend istream &operator >> (istream &is, mll &a) { return is >> a.val; }
	static mll Combination(ll a, ll b) {
		chmin(b, a - b);
		if (b < 0) return mll(0);
		mll c = 1;
		rep(i, b) c *= a - i;
		rep(i, b) c /= i + 1;
		return c;
	}
};
using vmll = std::vector<mll>;
using vvmll = std::vector<vmll>;
using vvvmll = std::vector<vvmll>;
using vvvvmll = std::vector<vvvmll>;

struct Fast {
	Fast() {
		cin.tie(0);
		ios::sync_with_stdio(false);
		cout << fixed << setprecision(std::numeric_limits<double>::max_digits10);
	}
} fast; //cin,cout高速化のおまじない＋桁数指定

ll mll::MOD = (ll)(1e9 + 7);// 998244353ll;


int main() {
	ll Q;
	cin >> Q;

	rep(q, Q) {
		string S;
		cin >> S;
		ll len_S = S.size();
		string T;
		cin >> T;
		ll len_T = T.size();
		
		vvll dp(len_S + 1, vll(len_T + 1, 0));
		reps(j, 1, len_S) {
			reps(i, 1, len_T) {
				if (S[j - 1] == T[i - 1]) {
					ll a = max(dp[j - 1][i], dp[j][i - 1]);
					dp[j][i] = max(a, dp[j - 1][i - 1] + 1);
				}
				else {
					dp[j][i] = max(dp[j - 1][i], dp[j][i - 1]);
				}
			}
		}

		ll result = dp[len_S][len_T];
		cout << result << endl;
	}

	return 0;
}

C++: #include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define MAX_N 1001

int solve(std::string s,std::string t){
        int dp[MAX_N][MAX_N]={0};
        int n,m;
        n=s.size();
       m=t.size();
        for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                        if(s[i]==t[j])
                                dp[i+1][j+1]=dp[i][j]+1;
                        else
                                dp[i+1][j+1]=std::max(dp[i][j+1],dp[i+1][j]);
                }
        }
        return dp[n][m];
}

int main(){
        int q;
        std::cin>>q;
        for(int i=0;i<q;i++){
                std::string s,t;
                std::cin >> s>>t;
                std::cout<<solve(s,t)<<std::endl;
        }
        return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

int main() {
  int q; cin >> q;
  string A, B;
  for (int i=0; i<q; i++) {
    cin >> A >> B;
    vector<vector<int>> LCS(A.length()+1, vector<int>(B.length()+1,0));
    for (int j=1; j<=A.length(); j++) {
      for (int k=1; k<=B.length(); k++) {
        if(A[j]==B[k]) LCS[j][k]=LCS[j-1][k-1]+1;
        else LCS[j][k]=max(LCS[j-1][k],LCS[j][k-1]);
      }
    }
    cout << max({LCS[A.length()][B.length()],LCS[A.length()-1][B.length()],LCS[A.length()][B.length()-1]}) << "\n";
  }
}

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

string u, v;
vector<vector<int> > memoization;

int lenLCS(int i, int j) {
  int current_max = INT_MIN;
  int attempt;
  if (i == -1)
    return 0;
  if (j == -1)
    return 0;
  if (memoization[i][j] != -1)
    return memoization[i][j];
  if (u[i] == v[j]) {
    attempt = 1 + lenLCS(i-1,j-1);
    if (attempt > current_max)
      current_max = attempt;
  }
  attempt = lenLCS(i-1,j);
  if (attempt > current_max)
    current_max = attempt;
  attempt = lenLCS(i,j-1);
  if (attempt > current_max)
    current_max = attempt;
  memoization[i][j] = current_max;
  return memoization[i][j];
}

int main(int argc, char **argv) {
  ios_base::sync_with_stdio(false);
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> u >> v;
    memoization = vector<vector<int> > (u.size(), vector<int> (v.size(), -1));
    cout << lenLCS(u.size()-1, v.size()-1) << endl;
  }
  return 0;
}

C++: #include <stdio.h>
#include <string.h>

#define M 1001

int n;

char x[M],y[M];
 
void lcs(void){
  int i,j;
  int len_x, len_y,graph[M][M];

  len_x=strlen(x);
  len_y=strlen(y);
  for(i=1;i<M;i++){
    for(j=1;j<M;j++){
      graph[i][j]=0;
    }
  }
  for(i=1;i<=len_x;i++){
    for(j=1;j<=len_y;j++){
      if(x[i-1]==y[j-1]) graph[i][j]=graph[i-1][j-1]+1;

      else{
        if(graph[i-1][j]>=graph[i][j-1]) graph[i][j]=graph[i-1][j];
        else graph[i][j]=graph[i][j-1];
      }
    }
  }
  printf("%d\n",graph[len_x][len_y]);
}
     
int main()
{
  int i;
   
  scanf("%d",&n);
 
  for(i=0;i<n;i++){
    scanf("%s",x);
    scanf("%s",y);
    lcs();
  }
  return 0;
}