Go: package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

const N = 1001

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

func lcs(x, y string) int {
	var c [N][N]int
	m := len(x)
	n := len(y)
	var maxl int

	x = " " + x
	y = " " + y

	for i := 1; i <= m; i++ {
		for 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
}

func answer(reader io.Reader) string {
	sc := bufio.NewScanner(reader)
	sc.Split(bufio.ScanWords)

	sc.Scan()
	q, _ := strconv.Atoi(sc.Text())

	var out bytes.Buffer
	for i := 0; i < q; i++ {
		sc.Scan()
		s1 := sc.Text()
		sc.Scan()
		s2 := sc.Text()
		out.WriteString(fmt.Sprintf("%d\n", lcs(s1, s2)))
	}
	return strings.TrimRight(out.String(), "\n")
}

func main() {
	fmt.Println(answer(os.Stdin))
}

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

#if __has_include("print.hpp")
  #include "print.hpp"
#endif

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

typedef long long ll;
typedef pair<int, int> p;

int n, w;
vector<vector<int>> dp(500, vector<int>(10500, -1));
vector<int> vv;
vector<int> wv;

void solve(){
  for (int i = n - 1; i >= 0; i--) {
    for (int j = 0; j < w; j++) {
      if(j < wv[i]){
        dp[i][j] = dp[i+1][j];
      }else{
        dp[i][j] = max(dp[i+1][j], dp[i+1][j-wv[i]] + vv[i]);
      }
    }
  }
}

int main(){
  cin >> n >> w;
  for (int i = 0; i < n; i++)
  {
    int tmp1, tmp2;
    cin >> tmp1 >> tmp2;
    wv.push_back(tmp1);
    vv.push_back(tmp2);
  }

  solve();
  cout << dp[0][w] << endl;
}

C++: #include <iostream> 
#include <cstring> 
using namespace std;
int c[1001][1001];

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


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

int main()
{
    
    //freopen("in1.txt","r",stdin);
    string x,y;
    int q;
    cin>>q;
    while(q--)
    {
        cin>>x>>y;
        int ans = lcs(x, y);
        cout<<ans<<endl;
    }
    return 0;
}

C++: #include<iostream>
#include<string>
using namespace std;
 
int main(){
  int c[1001][1001];
  string x,y;
  int n; cin >> n;
  while(n>0){
    n--;
    
    //文字列の入力
    cin >> x;
    cin >> y;

    //入力した文字列の長さをもとめる
    int lenx = x.size();
    int leny = y.size();
 
    //初期条件
    for(int i = 1; i <= lenx; i++){
      c[i][0] = 0;
    }
    
    //初期条件
    for(int j = 1; j <= leny; j++){
      c[0][j] = 0;
    }


    //LCS
    for(int i = 1; i <= lenx; i++){
      for(int j = 1; j <= leny; j++){
	//着目している文字が等しいとき
    if(x[i-1]==y[j-1]){
      c[i][j] = c[i-1][j-1] + 1;
      //着目している文字が等しくないときは
      //表の左と上の小さいほうを出力
    }else if(c[i-1][j] >= c[i][j-1]){
      c[i][j] = c[i-1][j];
    }else{
      c[i][j] = c[i][j-1];
    }
      }
    }
    
    //出力
    cout << c[lenx][leny] << 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];
bool dpR[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 lcmRec(char* X, char* Y, int nx, int ny) {
	if(nx <=0 || ny <= 0) return 0;
	if(!dpR[nx][ny]) {
		dpR[nx][ny] = 1;
		dp[nx][ny] = lcmRec(X, Y, nx-1, ny-1) + (X[nx-1]==Y[ny-1]);
		dp[nx][ny] = std::max(lcmRec(X, Y, nx-1, ny), dp[nx][ny]);
		dp[nx][ny] = std::max(lcmRec(X, Y, nx, ny-1), dp[nx][ny]);
	}
	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));
		printf("%d\n", lcmRec(X, Y, nx, ny));
	}
}

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

const int MAX_LENGTH = 1024;

char A[MAX_LENGTH + 1];
char B[MAX_LENGTH + 1];

int tu[MAX_LENGTH][MAX_LENGTH];

void lcs(int, int);

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i)
	{
		cin >> A >> B;
		int lA = strlen(A), lB = strlen(B);
		lcs(lA, lB);
		cout << tu[lA][lB] << endl;
	}

}

void lcs(int lA, int lB)
{
	for (int i = 0; i < lA; ++i)
		tu[0][i] = 0;
	for (int i = 0; i < lB; ++i)
		tu[i][0] = 0;

	for (int i = 1; i <= lA; i++)
	{
		for (int j = 1; j <= lB; j++)
		{
			if (A[i-1] == B[j-1])
				tu[i][j] = tu[i - 1][j - 1] + 1;
			else
				tu[i][j] = max(tu[i][j - 1], tu[i - 1][j]);
		}
	}
}

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

static const int N = 1000;

int Ics(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 = 0; i <= m; i++ ) c[i][0] = 0;
	for ( int j = 1; j <= n; j++ ) c[0][j] = 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 << Ics(s1, s2) << endl;
	}
	return 0;
}

C++: #include <cstdio>
#include <cstring>

int max(int a,int b){
  if(a<b)return b;
  else return a;
}

int main(void){
  char x[1005]={0};
  char y[1005]={0};
  int set=0;
  int dp[1005][1005]={0};
  /*dp[i][j]は、xのi文字目とyのj文字目での最長部分列*/
  scanf("%d",&set);
  int p=0,i=0,j=0;;
  for(p=0;p<set;p++){
    scanf("%s%s",x,y);
    int xl,yl;
    xl=strlen(x);yl=strlen(y);
    int ma,mb,mc;
    for(i=1;i<xl+1;i++){
      for(j=1;j<yl+1;j++){
	ma=dp[i][j-1];
	mb=dp[i-1][j];
	mc=dp[i-1][j-1];
	if(x[i-1]==y[j-1])mc++;
	//dp[i][j]= ma<mb ? (mb<mc ? mc : mb) : ma;
	dp[i][j]= max(ma,max(mb,mc));
      }
    }
    printf("%d\n",dp[xl][yl]);
  }
  return 0;
}

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

string X;
string Y;

int calc(int x_s, int x, int y, int length){
    if (X[x] == '\0') return length;
    int y_ = Y.find(X[x], y);
    if (y_ == string::npos) {
        if ((Y[y+1] == '\0')) {
            return max(length, calc(x_s + 1, x_s + 1, 0, 0));
        }
        return max(length, calc(x_s, x, y + 1, length));
    }
    return calc(x_s, x + 1, y_ + 1, length + 1);
}

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

    return 0;
}