Problem:
Score : 100 points

Problem Statement

You are given strings s and t.
Find one longest string that is a subsequence of both s and t.

Notes

A subsequence of a string x is the string obtained by removing zero or more characters from x and concatenating the remaining characters without changing the order.

Constraints

s and t are strings consisting of lowercase English letters.

1 \leq |s|, |t| \leq 3000

Input

Input is given from Standard Input in the following format:

s
t

Output

Print one longest string that is a subsequence of both s and t.
If there are multiple such strings, any of them will be accepted.

Sample Input 1

axyb
abyxb

Sample Output 1

axb

The answer is axb or ayb; either will be accepted.

Sample Input 2

aa
xayaz

Sample Output 2

aa

Sample Input 3

a
z

Sample Output 3

The answer is (an empty string).

Sample Input 4

abracadabra
avadakedavra

Sample Output 4

aaadara

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;

class Program {
    static void Main(string[] args) {
        string s = Console.ReadLine();
        string t = Console.ReadLine();
        int len_s = s.Length;
        int len_t = t.Length;

        //dpテーブルを用意する
        var dp = new int[len_s, len_t];
        if (s[0] == t[0]) {
            dp[0, 0] = 1;
        } else {
            dp[0, 0] = 0;
        }
        //初期化できるところは初期化する
        for (int i = 1; i < len_s; i++) {
            if (s[i] == t[0]) {
                dp[i, 0] = 1;
            } else {
                dp[i, 0] = Math.Max(dp[i - 1, 0], dp[i, 0]);
            }
        }
        for (int j = 1; j < len_t; j++) {
            if (t[j] == s[0]) {
                dp[0, j] = 1;
            } else {
                dp[0, j] = Math.Max(dp[0, j - 1], dp[0, j]);
            }
        }

        //dp開始
        for (int i = 1; i < len_s; i++) {
            for (int j = 1; j < len_t; j++) {
                int value = 0;
                if (s[i] == t[j]) {
                    value = dp[i - 1, j - 1] + 1;
                }
                int value2 = dp[i - 1, j];
                int value3 = dp[i, j - 1];

                value = Math.Max(value, Math.Max(value2, value3));

                dp[i, j] = value;
            }
        }

        //dpの復元
        string ans = "";
        int ind_i = len_s - 1;
        int ind_j = len_t - 1;
        while (true) {
            if (ind_i >= 1 && ind_j >= 1) {
                if (dp[ind_i, ind_j] == dp[ind_i, ind_j - 1]) {
                    ind_j--;
                } else if (dp[ind_i, ind_j] == dp[ind_i - 1, ind_j]) {
                    ind_i--;
                } else {
                    ans = s[ind_i] + ans;
                    ind_i--;
                    ind_j--;
                }
            }

            //終了条件
            if (ind_i == 0 && ind_j == 0) {
                if (dp[ind_i, ind_j] == 1) {
                    ans = s[0] + ans;
                }
                break;
            } else if (ind_j == 0) {
                if (dp[ind_i, ind_j] == 1 && dp[ind_i - 1, ind_j] == 0) {
                    ans = t[0] + ans;
                    break;
                } else {
                    ind_i--;
                }
            } else if (ind_i == 0) {
                if (dp[ind_i, ind_j] == 1 && dp[ind_i, ind_j - 1] == 0) {
                    ans = s[0] + ans;
                    break;
                } else {
                    ind_j--;
                }
            }

        }
        Console.WriteLine(ans);
    }
}