Problem: 2050E - Three Strings
Language: c++17 

Solution 1 (runtime: 62 ms):
#include <iostream>
#include <vector>
#include <string>
#include <limits>
#include <cstring>

using namespace std;

int countMinChanges_recursive(string& a, string& b, string& c, int ia, int ib) {
    const int ic = ia + ib;

    if (ia == a.length()) {
        int count = 0;

        for (int i = ib; i < b.length(); i++) {
            count += (b[i] != c[ic + i - ib]);
        }

        return count;
    } else if (ib == b.length()) {
        int count = 0;

        for (int i = ia; i < a.length(); i++) {
            count += (a[i] != c[ic + i - ia]);
        }

        return count;
    }

    if (a[ia] == b[ib]) return (c[ic] != a[ia]) + min(countMinChanges_recursive(a, b, c, ia + 1, ib), countMinChanges_recursive(a, b, c, ia, ib + 1));
    if (c[ic] == a[ia]) return min(countMinChanges_recursive(a, b, c, ia + 1, ib), 1 + countMinChanges_recursive(a, b, c, ia, ib + 1));
    if (c[ic] == b[ib]) return min(1 + countMinChanges_recursive(a, b, c, ia + 1, ib), countMinChanges_recursive(a, b, c, ia, ib + 1));
    return 1 + min(countMinChanges_recursive(a, b, c, ia + 1, ib), countMinChanges_recursive(a, b, c, ia, ib + 1));
}

int countMinChanges(string& a, string& b, string& c) {
    short table[a.length() + 1][b.length() + 1];    // `table[ia][ib] = countMinChanges(a, b, c, ia, ib)`

    // Base cases
    table[a.length()][b.length()] = 0;
    for (int ia = a.length() - 1; ia >= 0; ia--) {
        table[ia][b.length()] = table[ia + 1][b.length()] + (a[ia] != c[ia + b.length()]);
    }
    for (int ib = b.length() - 1; ib >= 0; ib--) {
        table[a.length()][ib] = table[a.length()][ib + 1] + (b[ib] != c[ib + a.length()]);
    }

    for (int ia = a.length() - 1; ia >= 0; ia--) {
        for (int ib = b.length() - 1; ib >= 0; ib--) {
            const int ic = ia + ib;

            if (a[ia] == b[ib])
                table[ia][ib] = (c[ic] != a[ia]) + min(table[ia + 1][ib], table[ia][ib + 1]);
            else if (c[ic] == a[ia])
                table[ia][ib] = min(table[ia + 1][ib], (short) (1 + table[ia][ib + 1]));
            else if (c[ic] == b[ib])
                table[ia][ib] = min((short) (1 + table[ia + 1][ib]), table[ia][ib + 1]);
            else 
                table[ia][ib] = 1 + min(table[ia + 1][ib], table[ia][ib + 1]);
        }
    }

    return table[0][0];
}

int main(void) {
    int t;
    cin >> t;

    while (t--) {
        string a, b, c;
        cin >> a >> b >> c;

        cout << countMinChanges(a, b, c) << '\n';
    }

    return 0;
}

Solution 2 (runtime: 1186 ms):
#include <bits/stdc++.h>

using namespace std;

int dp[2005][2005];

int solve(char *a, int an, char *b, int bn, char *c, int cn){
    if(dp[an][bn] != -1) return dp[an][bn];
    if(an == 0 && bn == 0){
        dp[an][bn] = 0;
        return dp[an][bn];
    }

    dp[an][bn] = cn;
    if(an != 0)
        dp[an][bn] = min(dp[an][bn], solve(a+1, an-1, b, bn, c+1, cn-1) + (a[0] != c[0]));
    if(bn != 0)
        dp[an][bn] = min(dp[an][bn], solve(a, an, b+1, bn-1, c+1, cn-1) + (b[0] != c[0]));

    return dp[an][bn];
}

int main(){
    int t;
    char a[2005], b[2005], c[2005];
    int an, bn, cn;

    cin >> t;
    while(t--){
        //reset the dp array
        memset(dp, -1, 2005*2005*sizeof(int));

        scanf("%s%s%s", a, b, c);

        //find the size of the strings
        for(an = 0; a[an]; an++);
        for(bn = 0; b[bn]; bn++);
        for(cn = 0; c[cn]; cn++);

        cout << solve(a, an, b, bn, c, cn) << '\n';
    }
    return 0;
}