Problem: 2050E - Three Strings
Language: java

Solution 1 (runtime: 624 ms):
import java.io.*;
import java.lang.reflect.Array;
import java.util.*;

public class MyClass {
    public static void main(String[] args) {
        FastScanner in = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        int t = in.nextInt();
        while (t-- > 0)
            solve(in, out);
        out.close();
    }
    static long pow(long x,long n, long m) {
        if(n==0) return 1;
        else if(n%2==0) return pow((x*x)%m,n/2,m)%m;
        else return (x*pow((x*x)%m,n/2,m))%m;
    }

    static int gcd(int a,int b) {
        if(b==0) return a;
        else return gcd(b,a%b);
    }

    static int ans;
    static void findSum(int[][] a,int i, int j, int sum) {
        if(i>2 || j>2) return;
        findSum(a,i,j+1, a[i][j]+sum);
        findSum(a,i+1,j, a[i][j]+sum);
        if(i==2 && j==2) ans=Math.min(a[i][j]+sum, ans);
    }

    static char[] a,b,c;
    static int A[][];
    static int findMaxMatching(int i, int j, int k){
        if(i>=a.length){
            int total=0;
            for (int l = j; l < b.length; l++) {
                if(b[l]==c[k]){
                   total++;
                }
                k++;
            }
            return total;
        }
        if(j>=b.length){
            int total=0;
            for (int l = i; l < a.length; l++) {
                if(a[l]==c[k]){
                    total++;
                }
                k++;
            }
            return total;
        }
        if(A[i][j]>0) return A[i][j];
        int possibilityA = findMaxMatching(i+1,j,k+1);
        if(a[i]==c[k]){
            possibilityA++;
        }
        int possibilityB = findMaxMatching(i,j+1,k+1);
        if(b[j]==c[k]){
            possibilityB++;
        }
        A[i][j] = Math.max(possibilityA, possibilityB);
        return A[i][j];
    }
    static void solve(FastScanner in,PrintWriter out) {
        a=in.next().toCharArray();
        b=in.next().toCharArray();
        c=in.next().toCharArray();
        A=new int[a.length][b.length];
        int max = findMaxMatching(0,0,0);
        out.println(c.length-max);
    }

    static class pair<U extends Comparable<U>, V extends Comparable<V>> implements Comparable<pair<U, V>> {
        public U x;
        public V y;

        public pair(U x, V y) {
            this.x = x;
            this.y = y;
        }

        public int compareTo(pair<U, V> other) {
            int i = other.y.compareTo(y);
            if (i != 0) return i;
            return other.x.compareTo(x);
        }

        public String toString() {
            return x.toString() + " " + y.toString();
        }

        public boolean equals(Object obj) {
            if (this.getClass() != obj.getClass()) return false;
            pair<U, V> other = (pair<U, V>) obj;
            return x.equals(other.x) && y.equals(other.y);
        }

        public int hashCode() {
            return 31 * x.hashCode() + y.hashCode();
        }

    }

    static void sort(int[] a) {
        ArrayList<Integer> l=new ArrayList<>();
        for (int i:a) l.add(i);
        Collections.sort(l);
        for (int i=0; i<a.length; i++) a[i]=l.get(i);
    }
    static void sortR(int[] a) {
        ArrayList<Integer> l=new ArrayList<>();
        for (int i:a) l.add(i);
        Collections.sort(l,Collections.reverseOrder());
        for (int i=0; i<a.length; i++) a[i]=l.get(i);
    }

    static class FastScanner {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        String next() {
            while (!st.hasMoreTokens())
                try {
                    st=new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }
        int[] readArray(int n) {
            int[] a=new int[n];
            for (int i=0; i<n; i++) a[i]=nextInt();
            return a;
        }
        long nextLong() {
            return Long.parseLong(next());
        }
    }
}

Solution 2 (runtime: 280 ms):
import java.util.*;

import java.lang.*;

import java.io.*;



public class Codeforces {

    public static void main(String[] args){

        FastReader fr = new FastReader();

        int tc = fr.nextInt();



        while (tc-- > 0) {

            solve(fr);

        }

    }





    private static void solve(FastReader fr) {

        String a = fr.next();

        String b = fr.next();

        String c = fr.next();

        int[][] dp = new int[a.length()+1][b.length()+1];



        for(int[] row : dp) Arrays.fill(row, -1);



        System.out.println(solve(a, b, c, 0, 0, 0, dp));

    }



    static int solve(String a, String b, String c, int i, int j, int k, int[][] dp) {

        if(k == c.length()) return 0;

        if(i > a.length() || j > b.length()) return (int)(1e7);

        boolean isAMatch = false;

        boolean isBMatch = false;



        if(dp[i][j] != -1) return dp[i][j];



        if(i < a.length() && a.charAt(i) == c.charAt(k)){

            isAMatch = true;

        }



        if(j < b.length() && b.charAt(j) == c.charAt(k)){

            isBMatch = true;

        }



        int ans1 = solve(a, b, c, i+1, j, k+1, dp) + (isAMatch ? 0 : 1);

        int ans2 = solve(a, b, c, i, j + 1, k+1, dp) + (isBMatch ? 0 : 1);



        return dp[i][j] = Math.min(ans1, ans2);

    }





    static int[] readIntArray(FastReader fr, int n){

        int[] arr = new int[n];



        for(int i = 0; i < n; i++){

            arr[i] = fr.nextInt();

        }



        return arr;

    }



    static class FastReader {

        BufferedReader br;

        StringTokenizer st;



        public FastReader() {

            br = new BufferedReader(

                    new InputStreamReader(System.in));

        }



        String next() {

            while (st == null || !st.hasMoreElements()) {

                try {

                    st = new StringTokenizer(br.readLine());

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

            return st.nextToken();

        }



        int nextInt() {

            return Integer.parseInt(next());

        }



        long nextLong() {

            return Long.parseLong(next());

        }



        double nextDouble() {

            return Double.parseDouble(next());

        }



        String nextLine() {

            String str = "";

            try {

                if (st.hasMoreTokens()) {

                    str = st.nextToken("\n");

                } else {

                    str = br.readLine();

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

            return str;

        }

    }



}