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

Solution 1 (runtime: 109 ms):
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <bitset>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#define ll long long
#define int long long
#define pqi priority_queue<long long>
#define pi pair<long long, long long>
#define mi map<long long, long long>
#define vi vector<long long>
#define vvi vector<vector<long long>>

using namespace std;

int gcd(int a, int b){
    //a>b
    if(b==0) return a;
    return gcd(b,a%b);
}
istream &operator>>(istream &is, vector<int> &vec)
{
//    vec.clear();
    int num;
    while (is >> num)
    {
        vec.push_back(num);
        char ch = is.peek();
        if (ch == '\n')
        {
            is.ignore();
            break;
        }
    }
    return is;
}

void print(vector <int> v){
    for(auto it:v) cout << it <<' ';
    cout <<endl;
}
vector<int> prefixSum(vector<int> v ){
    vector<int> ans;
    int sum=0;
    for (int i =0; i < v.size();i++){
        sum+=v[i];
        ans.push_back(sum);
    }
    return ans;
}
void print(const vector<std::vector<int>> arr) {
    for (const std::vector<int>& row : arr) {
        for (int num : row) {

            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
}
void print (const map<int, vi>& sum) {
    for (const auto& pair : sum) {
        int key = pair.first;
        const vi& values = pair.second;

        cout << "Key: " << key << " -> Values: [";
        for (size_t i = 0; i < values.size(); ++i) {
            cout << values[i];
            if (i < values.size() - 1) {
                cout << ", ";
            }
        }
        cout << "]" << endl;
    }
}
void print( vector<set<int>>& cycles) {
    for (const auto& cycle : cycles) {
        cout << "{ ";
        for (auto it = cycle.begin(); it != cycle.end(); ++it) {
            cout << *it;
            if (next(it) != cycle.end()) {
                cout << ", ";
            }
        }
        cout << " }" << endl;
    }
}
const int mod = 1e9 + 7;
const int N= 2e5 + 5;
int64_t fact[N];
int64_t pw(int64_t a, int64_t b) {
    int64_t r = 1;
    while(b > 0) {
        if(b & 1) r = (r * a) % mod;
        b /= 2;
        a = (a * a) % mod;
    }
    return r;
}
int64_t C(int64_t n, int64_t k) {
    if(n < k) return 0LL;
    return (fact[n] * pw((fact[n - k] * fact[k]) % mod, mod - 2)) % mod;
}


int modInverse(int a, int m) {
    int result = 1;
    int exp = m - 2;
    while (exp > 0) {
        if (exp % 2 == 1) {
            result = (result * a) % m;
        }
        a = (a * a) % m;
        exp /= 2;
    }
    return result;
}
vector<int> getDivisors(int n) {
    std::vector<int> divisors;
    
    // Loop from 1 to sqrt(n) to find divisors
    for (int i = 1; i <= std::sqrt(n); ++i) {
        if (n % i == 0) {
            divisors.push_back(i);
            // If i is not equal to n / i, add the corresponding divisor
            if (i != n / i) {
                divisors.push_back(n / i);
            }
        }
    }

    sort(divisors.begin(), divisors.end());
    return divisors;

}

int check(vi a, int d){
    int n = a.size();
    int m = 0, r = n-1, l = 0;
    int spare = 0 ;
    // cout << "d="<<d <<endl;

    while(l < r){
        if( a[l] > d){
            spare += (a[l] - d);
        }else if( a[l] < d){
            spare -= (d-a[l]);
            m += (d-a[l]);
            while( spare < 0){
                int k = min(a[r], -1* spare);
                spare += k;
                a[r] -= k;
                if (a[r] == 0) r--;
            }
        }
        l++;
    }
    // cout << "spare "<< spare << endl;
    return m + spare;
}

int f (int i, int j, string a, string b, string c, vector <vector <int>> &dp){
    int k = i + j;
    if(k == c.size()){
        return 0;
    }

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

    int ans = INT_MAX;

    if(i < a.size()){
        
        int t = f ( i+1 , j , a ,b ,c , dp);
        //match
        if(a[i] == c[k]){
            ans = min (ans, t);
        }
        //changed
        ans = min ( ans, t + 1);

    }
    if( j < b.size()){
        int t = f ( i , j+1 , a ,b ,c , dp);
        //match
        if(b[j] == c[k]){
            ans = min (ans, t);
        }
        //changed
        ans = min ( ans, t + 1);
    }

    return dp[i][j] = ans;

}

void solve() {
    string a, b, c;
    cin >> a >> b >> c;
    
    // dp[i][j] represents minimum operations needed when we've used
    // i characters from string a and j characters from string b
    vector<vector<int>> dp(a.size() + 1, vector<int>(b.size() + 1, INT_MAX));
    
    // Base case - when we haven't used any characters
    dp[0][0] = 0;
    
    // Fill dp table
    for(int i = 0; i <= a.size(); i++) {
        for(int j = 0; j <= b.size(); j++) {
            // Skip invalid states
            if(dp[i][j] == INT_MAX) continue;
            
            int k = i + j;  // position in string c
            if(k == c.size()) continue;  // we've formed the complete string
            
            // Try taking character from string a
            if(i < a.size()) {
                int cost = (a[i] == c[k]) ? 0 : 1;
                dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + cost);
            }
            
            // Try taking character from string b
            if(j < b.size()) {
                int cost = (b[j] == c[k]) ? 0 : 1;
                dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + cost);
            }
        }
    }
    
    // Find answer when we've used all characters needed to form string c
    int result = INT_MAX;
    for(int i = 0; i <= a.size(); i++) {
        for(int j = 0; j <= b.size(); j++) {
            if(i + j == c.size()) {
                result = min(result, dp[i][j]);
            }
        }
    }
    
    cout << (result == INT_MAX ? -1 : result) << endl;
}
 
int32_t main()
{

    ios_base ::sync_with_stdio(false);
    cin.tie(NULL);

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int T = 1;

//    fact[0] = 1;
//    for(int64_t i = 1; i < N; ++i) fact[i] = (fact[i - 1] * i) % mod;
//
   cin >> T;

    while (T--)
    {
        solve();
    }

    return 0;
}


Solution 2 (runtime: 62 ms):
#include<iostream>

#include<algorithm>

#include<vector>

using namespace std;

typedef long long ll;

vector<ll>p, q;

int s[2005][2005];

int check(char a, char b) {

	if (a == b) return 0;

	else return 1;

}

void slove() {

	string a, b, c;

	cin >> a >> b >> c;

	for (int i = 0; i <= a.length(); i++)

		for (int j = 0; j < b.length(); j++)

			s[i][j] = 0;

	for (int i = 0; i <= a.length(); i++) {

		for (int j = 0; j <= b.length(); j++) {

			if (i + j == 0) continue;

			if (i == 0) s[i][j] = s[i][j - 1] + check(b[j - 1], c[j - 1]);

			else if (j == 0) s[i][j] = s[i - 1][j] + check(a[i - 1], c[i - 1]);

			else  s[i][j] = min(s[i][j - 1] + check(b[j - 1], c[i + j - 1]), s[i - 1][j] + check(a[i - 1], c[j + i - 1]));

		}

	}

	cout << s[a.length()][b.length()] << "\n";

}

int main() {

	int ttt;

	cin >> ttt;

	while (ttt--) {

		slove();

	}

}