Problem: 2050E - Three Strings
Language: C++17 (GCC 7-32)

Previous submission (verdict: Time limit exceeded on test 6):
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <cmath>

using namespace std;

#define FAST_IO ios::sync_with_stdio(false); cin.tie(nullptr);

// Shortcuts
#define int long long
#define vl vector<long long>
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define invl(v, n) rep(i, n) cin >> v[i];

// Loop macros
#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep_range(i, a, b) for(int i = a; i < b; ++i)
#define rrep(i, n) for(int i = n - 1; i >= 0; --i)
#define for_each(x, container) for(auto &x : container)

// Sieve of primes
vector<bool> sieve(int n) {
    vector<bool> is_prime(n+1, true);
    is_prime[0] = is_prime[1] = false;

    rep(i, sqrt(n) + 1) {
        if (is_prime[i]) {
            for (int j = i * i; j <= n; j += i) {
                is_prime[j] = false;
            }
        }
    }
    return is_prime;
}

int hey(string a,string c, int m, int k)
{
    // If first string is empty, the only option is to
    // insert all characters of second string into first
    if (m == 0)
        return k;
 
    // If last characters of two strings are same, nothing
    // much to do. Ignore last characters and get count for
    // remaining strings.
    if (a[m - 1] == c[k - 1])
    {
        return hey(a, c, m - 1,k-1);
    }
    

 
    // If last characters are not same, consider all three
    // operations on last character of first string, recursively
    // compute minimum cost for all three operations and take
    // minimum of three values.
    return 1 + hey(a, c, m-1 ,k-1);
}


 
int editDist(string a, string b,string c, int m, int n, int k)
{
    // If first string is empty, the only option is to
    // insert all characters of second string into first
    if (m == 0)
        return hey(b, c, n,k);
 
    // If second string is empty, the only option is to
    // remove all characters of first string
    if (n == 0)
        return hey(a, c, m,k);
 
    // If last characters of two strings are same, nothing
    // much to do. Ignore last characters and get count for
    // remaining strings.
    if (a[m - 1] == c[k - 1] && b[n-1]!=c[k-1])
    {
        return min(editDist(a, b, c, m - 1, n,k-1),1+editDist(a, b, c, m, n-1,k-1));
    }
    if (b[n - 1] == c[k - 1] && a[m-1]!=c[k-1])
    {
        return min(editDist(a, b, c, m, n-1 ,k-1),1+editDist(a, b, c, m-1, n,k-1));
    }
    if (b[n - 1] == c[k - 1] && a[m-1]==c[k-1])
    {
        return min(editDist(a, b, c, m, n-1 ,k-1),editDist(a, b, c, m - 1, n,k-1));
    }

 
    // If last characters are not same, consider all three
    // operations on last character of first string, recursively
    // compute minimum cost for all three operations and take
    // minimum of three values.
    return 1 + min(editDist(a, b, c, m, n-1 ,k-1), // Insert
                   editDist(a, b, c, m-1, n ,k-1) // Remove
                   );
}

signed main() {
    FAST_IO
    int t;
    cin >> t;
    while(t--) {
        string a,b,c;
        cin>>a>>b>>c;
        int ans= editDist(a,b,c,a.size(),b.size(),c.size());
        cout<<ans<<endl;

        
        // Your logic here
    }
    return 0;
}

Submission (verdict: Time limit exceeded on test 16):
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <unordered_map>

using namespace std;

#define FAST_IO ios::sync_with_stdio(false); cin.tie(nullptr);

// Shortcuts
#define int long long
#define vl vector<long long>
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define invl(v, n) rep(i, n) cin >> v[i];

// Loop macros
#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep_range(i, a, b) for(int i = a; i < b; ++i)
#define rrep(i, n) for(int i = n - 1; i >= 0; --i)
#define for_each(x, container) for(auto &x : container)

// Memoization maps
unordered_map<string, int> memoHey;
unordered_map<string, int> memoEditDist;

// Helper function to create a unique key for memoization
string getKey(int m, int k) {
    return to_string(m) + "," + to_string(k);
}

string getKey(int m, int n, int k) {
    return to_string(m) + "," + to_string(n) + "," + to_string(k);
}

// Sieve of primes
vector<bool> sieve(int n) {
    vector<bool> is_prime(n + 1, true);
    is_prime[0] = is_prime[1] = false;

    rep(i, sqrt(n) + 1) {
        if (is_prime[i]) {
            for (int j = i * i; j <= n; j += i) {
                is_prime[j] = false;
            }
        }
    }
    return is_prime;
}


int hey(string &a, string &c, int m, int k) {
    // Create a unique key for the current state
    string key = to_string(m) + "," + to_string(k);
    
    // Check if the result for the current state is already computed
    if (memoHey.count(key)) 
        return memoHey[key];

    // Base case: if `m` is 0, return `k`
    if (m == 0) 
        return memoHey[key] = k;

    // If last characters match, recursively compute for the reduced size
    if (a[m - 1] == c[k - 1]) 
        return memoHey[key] = hey(a, c, m - 1, k - 1);

    // If last characters do not match, compute with the operation and store the result
    return memoHey[key] = 1 + hey(a, c, m - 1, k - 1);
}

// Memoized editDist function
int editDist(string &a, string &b, string &c, int m, int n, int k) {
    string key = getKey(m, n, k);
    if (memoEditDist.count(key)) return memoEditDist[key];

    if (m == 0){
        memoHey.clear();
        return memoEditDist[key] = hey(b, c, n, k);

    }
    if (n == 0){
        memoHey.clear();
        return memoEditDist[key] = hey(a, c, m, k);

    }
        
    

    if (a[m - 1] == c[k - 1] && b[n - 1] != c[k - 1])
        return memoEditDist[key] = min(
            editDist(a, b, c, m - 1, n, k - 1),
            1 + editDist(a, b, c, m, n - 1, k - 1)
        );

    if (b[n - 1] == c[k - 1] && a[m - 1] != c[k - 1])
        return memoEditDist[key] = min(
            editDist(a, b, c, m, n - 1, k - 1),
            1 + editDist(a, b, c, m - 1, n, k - 1)
        );

    if (b[n - 1] == c[k - 1] && a[m - 1] == c[k - 1])
        return memoEditDist[key] = min(
            editDist(a, b, c, m, n - 1, k - 1),
            editDist(a, b, c, m - 1, n, k - 1)
        );

    return memoEditDist[key] = 1 + min(
        editDist(a, b, c, m, n - 1, k - 1),
        editDist(a, b, c, m - 1, n, k - 1)
    );
}

signed main() {
    FAST_IO
    int t;
    cin >> t;
    while (t--) {
        string a, b, c;
        cin >> a >> b >> c;
        memoHey.clear();
        memoEditDist.clear();
        int ans = editDist(a, b, c, a.size(), b.size(), c.size());
        cout << ans << endl;
    }
    return 0;
}