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: 390 ms):
import java.util.*;

public class Q1 {
    public static long solve(long n, HashMap<Long, Long> map) {
        if (n <= 3) {
            return 1;
        }

        if (map.containsKey(n)) {
            return map.get(n);
        }

        long count = solve(n / 4, map) + solve(n / 4, map);
        map.put(n, count);
        return map.get(n);
    }

    public static long gcd(long a, long b) {
        if (a == 0)
            return b;
        if (b == 0)
            return a;

        // Base case
        if (a == b)
            return a;

        // a is greater
        if (a > b) {
            if (a % b == 0)
                return b;
            return gcd(a - b, b);
        }
        if (b % a == 0)
            return a;
        return gcd(a, b - a);
    }

    public static int solve(int ai, int ci, String a, String b, String c, int dp[][]) {
        int bi = ci - ai;
        if (ai == a.length()) {
            String s1 = b.substring(bi);
            String s2 = c.substring(ci);
            if (s1.equals(s2)) {
                return 0;
            }
            int cnt = 0;
            for (int i = 0; i < s1.length(); i++) {
                if (s1.charAt(i) != s2.charAt(i)) {
                    cnt++;
                }
            }

            return cnt;
        }

        if (bi == b.length()) {
            String s1 = a.substring(ai);
            String s2 = c.substring(ci);
            if (s1.equals(s2)) {
                return 0;
            }
            int cnt = 0;
            for (int i = 0; i < s1.length(); i++) {
                if (s1.charAt(i) != s2.charAt(i)) {
                    cnt++;
                }
            }

            return cnt;
        }

        if (dp[ai][ci] != -1) {
            return dp[ai][ci];
        }

        int min = Integer.MAX_VALUE;
        if (a.charAt(ai) == c.charAt(ci)) {
            min = Math.min(solve(ai + 1, ci + 1, a, b, c, dp), min);
        }

        if (b.charAt(bi) == c.charAt(ci)) {
            min = Math.min(solve(ai, ci + 1, a, b, c, dp), min);
        }

        if (a.charAt(ai) != c.charAt(ci) || b.charAt(bi) != c.charAt(ci)) {
            min = Math.min(1 + Math.min(solve(ai + 1, ci + 1, a, b, c, dp), solve(ai, ci + 1, a, b, c, dp)), min);
        }

        return dp[ai][ci] = min;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            String a = sc.next();
            String b = sc.next();
            String c = sc.next();
            int dp[][] = new int[a.length()][c.length()];
            for (int row[] : dp) {
                Arrays.fill(row, -1);
            }
            System.out.println(solve(0, 0, a, b, c, dp));
        }
    }
}