Problem: 2050E - Three Strings
Language: java

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

public class E {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);

        int tc = Integer.parseInt(br.readLine());

        while (tc-- > 0) {
            String s1 = br.readLine();
            String s2 = br.readLine();
            String s3 = br.readLine();

            int[][] dp = new int[s2.length()+1][s1.length()+1];

            for (int c = 1; c < dp[0].length; c++) {
                dp[0][c] = dp[0][c-1];                
                if (s3.charAt(c-1) != s1.charAt(c-1)) {
                    dp[0][c]++;
                }
            }

            for (int r = 1; r < dp.length; r++) {
                dp[r][0] = dp[r-1][0];
                if (s3.charAt(r-1) != s2.charAt(r-1)) {
                    dp[r][0]++;
                }
            }

            for (int r = 1; r < dp.length; r++) { // r = s2 used
                for (int c = 1; c < dp[0].length; c++) { // c = s1 used
                    int s1add = s3.charAt(r+c-1) == s1.charAt(c-1) ? 0 : 1;
                    int s2add = s3.charAt(r+c-1) == s2.charAt(r-1) ? 0 : 1;

                    dp[r][c] = Math.min(dp[r-1][c] + s2add, dp[r][c-1] + s1add);
                }
            }
            
            pw.println(dp[s2.length()][s1.length()]);
        }

        pw.close();
    }
}


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

public class ThreeStrings {
    // Custom print functions
    public static void print(Object print) {
        System.out.print(print);
    }

    public static void println(Object print) {
        System.out.println(print);
    }

    public static void println() {
        System.out.println();
    }

    // Declare a 2D dp array to store memoization results
    static int[][] dp;

    // Function to compute the minimum changes required
    public static int func(int i, int j, char[] a, char[] b, char[] c) {
        int n = c.length;
        // Base case: if all characters are matched
        if (i + j >= n) return 0;

        // Check if result is already calculated
        if (dp[i][j] != -1) return dp[i][j];

        int take_a = Integer.MAX_VALUE;
        int take_b = Integer.MAX_VALUE;

        // Try taking a character from 'a'
        if (i < a.length) {
            if (a[i] == c[i + j]) {
                take_a = func(i + 1, j, a, b, c); // No change needed
            } else {
                take_a = 1 + func(i + 1, j, a, b, c); // Change needed
            }
        }

        // Try taking a character from 'b'
        if (j < b.length) {
            if (b[j] == c[i + j]) {
                take_b = func(i, j + 1, a, b, c); // No change needed
            } else {
                take_b = 1 + func(i, j + 1, a, b, c); // Change needed
            }
        }

        // Store and return the minimum changes required
        return dp[i][j] = Math.min(take_a, take_b);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt(); // Number of test cases

        for (int l = 0; l < t; l++) {
            char[] a = sc.next().toCharArray(); // Input string a
            char[] b = sc.next().toCharArray(); // Input string b
            char[] c = sc.next().toCharArray(); // Target string c

            int m = a.length;
            int n = b.length;
            int len = c.length;

            // Initialize dp array with -1
            dp = new int[m + 1][n + 1];
            for (int[] row : dp) {
                Arrays.fill(row, -1);
            }

            // Compute and print result
            println(func(0, 0, a, b, c));
        }
        sc.close();
    }
}