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 <cmath>
#define MAX 1001
using namespace std;

int Lcc(const char *X, const char *Y) {
    int lcc = 0;
    int dp[MAX][MAX];
    for (int i=0; i<MAX; i++)
        for (int j=0; j<MAX; j++) dp[i][j] = 0;

    int x=0, y=0;
    for (int i=0;;i++) {
        if (X[i] == ',') {x = i;break;}
        for (int j=0;;j++) {
            if (Y[j] == ',') {
                y = j;
                break;
            } else {
                if (X[i] == Y[j]) {
                    dp[i+1][j+1] = fmax(dp[i][j] + 1, dp[i+1][j]);
                } else {
                    dp[i+1][j+1] = fmax(dp[i+1][j], dp[i][j+1]);
                }
            }
        }
    }
    return dp[x-1][y-1];
}

int
main()
{
    int q;
    scanf("%d", &q);
    for (int i=0; i<(q); i++) {
        char X[MAX], Y[MAX];
        for (int i=0; i<MAX; i++) {
            X[i] = ','; Y[i] = ',';
        }
        scanf(" %s", X);scanf(" %s", Y);
        int LCC = Lcc(X, Y);
        printf("%d\n", LCC);
    }
    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;
  c[0][0] = 0;
  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 = 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]);
    }
  }javascript:void(0)

  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++: #define _USE_MATH_DEFINES

#include <array>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <utility>
#include <tuple>
#include <algorithm>
#include <limits>
#include <fstream>
#include <numeric>
#include <stack>
#include <queue>
#include <list>
#include <cstring>
#include <unordered_set>
#include <cmath>
#include <iomanip>

namespace
{
	template<int N>
	std::array<int, N> GetValue(std::istream& stream)
	{
		std::string buf;
		std::getline(stream, buf);

		std::stringstream sstr(buf);
		std::array<int, N> retval;

		for (int i = 0; i < N; ++i)
		{
			std::getline(sstr, buf, ' ');
			retval[i] = std::stoi(buf);
		}

		return retval;
	}

	std::vector<int> GetValue(std::istream& stream, int num, char delim)
	{
		std::string buf;
		std::getline(stream, buf);
		std::stringstream sstr(buf);

		std::vector<int> retval;
		retval.reserve(num);

		std::string input;;
		for (int i = 0; i < num && std::getline(sstr, input, delim); ++i)
		{
			retval.push_back(std::stoi(input));
		}

		return retval;
	}

	int GetValue(std::istream& stream)
	{
		int in;
		stream >> in;

		return in;
	}

	std::vector<std::string> GetValueString(std::istream& stream, int num, char delim)
	{
		std::string buf;
		std::vector<std::string> retval;
		retval.reserve(num);

		std::getline(stream, buf);
		std::stringstream sstr(buf);

		for (int i = 0; i < num && std::getline(sstr, buf, delim); ++i)
		{
			retval.push_back(std::move(buf));
		}

		return retval;
	}

	template<typename Itr>
	void PrintLine(Itr begin, Itr end)
	{
		bool first = true;

		for (int i = 0; begin != end; ++begin, ++i)
		{
			if (!first)
			{
				std::cout << ' ';
			}

			std::cout << (*begin);

			first = false;
		}
		std::cout << std::endl;
	}

	template<typename T>
	void Print(const std::vector<T>& sequence)
	{
		for (const auto& e : sequence)
		{
			std::cout << e << '\n';
		}

		std::cout << std::flush;
	}

	const int kLen = 1000;
	int c[kLen + 1][kLen + 1] = {};

	int Lcs(std::string x, std::string y)
	{
		int m = x.size();
		int n = y.size();

		int max = 0;

		x = ' ' + x;
		y = ' ' + y;

		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] = std::max(c[i - 1][j], c[i][j - 1]);
				}
				max = std::max(max, c[i][j]);
			}
		}

		return max;
	}
}

int main(int argc, char* argv[])
{
	auto file = (argc == 1) ? std::ifstream() : std::ifstream(argv[1]);
	std::istream& stream = (argc == 1) ? std::cin : file;
	if (argc == 1)
	{
		std::cin.tie(0);
		std::ios::sync_with_stdio(false);
	}

	int num;
	stream >> num;
	std::string x, y;

	for (int i = 0; i < num; ++i)
	{
		stream >> x >> y;
		std::cout << Lcs(x, y) << std::endl;
	}
}

C++: #include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <cassert>
#include <climits>
#include <vector>
using namespace std;

#define DEBUG (0)

#if DEBUG
#define DPRINTF(...) do { \
    printf("D(L%d) %s: ", __LINE__, __func__); \
    printf(__VA_ARGS__); \
  } while (false)
#else
#define DPRINTF(...)
#endif // DEBUG


vector<string> getCombinations(string str, int len)
{
  assert(0 < len && len <= str.length());

  vector<string> combinations;

  if (len == 1)
  {
    for (int i = 0; i < str.length(); i++)
      combinations.push_back(str.substr(i, 1));

    return combinations;
  }

  for (int i = 0; i <= str.length() - len; i++)
  {
    const char c = str[i];
    vector<string> recursive = getCombinations(str.substr(i+1), len - 1);

    for (string str : recursive)
      combinations.push_back(c + str);
  }

  return combinations;
}


bool findCombination(string src, string find)
{
  vector<string> combinations = getCombinations(src, find.length());

  for (string str : combinations)
  {
    if (str == find)
      return true;
  }

  return false;
}


int getLCSlen(string s0, string s1)
{
  const string* pStrLong;
  const string* pStrShort;

  if (s0.length() < s1.length())
  {
    pStrShort = &s0;
    pStrLong = &s1;
  }
  else
  {
    pStrShort = &s1;
    pStrLong = &s0;
  }


  const int kLenInvalid = -1;
  int longestLen = kLenInvalid;
  int len = pStrShort->length();

  while (longestLen == kLenInvalid && len > 0)
  {

    vector<string> candidates = getCombinations(*pStrShort, len);

#if DEBUG & 0
    for (string str : candidates)   DPRINTF("%s\n", str.c_str());
#endif // DEBUG

    for (string candidate : candidates)
      if (findCombination(*pStrLong, candidate))
        longestLen = len;

    len--;

  }

  return longestLen;
}


int main()
{
  int numOfPair;
  cin >> numOfPair; cin.ignore();

  DPRINTF("num of pair %d\n", numOfPair);

  for (int i = 0; i < numOfPair; i++)
  {
    string str0, str1;
    cin >> str0 >> str1; cin.ignore();

    DPRINTF("str0 %s  str1 %s\n", str0.c_str(), str1.c_str());

    cout << getLCSlen(str0, str1) << endl;
  }

  return 0;
}