Problem: 2050E - Three Strings
Language: C++20 (GCC 13-64)

Previous submission (verdict: Wrong answer on test 1):
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define forn(i,n) for(int i = 0; i < n; i++)
#define vi vector<int>
#define mii map<int,int>
#define pb push_back
#define en "\n"
#define cyes cout<<"YES\n"
#define cno cout<<"NO\n"
#define int long long
#define pii pair<int, int>
const int N = 1e3+2, MOD = 1e9+7;
/*
struct item{
    int m,c;
};
 
struct segtree{
    int size;
    vector<item> values;
 
    item NEUTRAL_ELEMENT = {INT_MAX, 0}; //change pt
 
    item merge(item a, item b){
        if(a.m < b.m) return a;
        if(b.m < a.m) return b;
        return {a.m, a.c + b.c};
    }
 
    item single(int v){
        return {v,1};
    }
 
    void init(int n) {
        size = 1;
        while(size < n) size *= 2;
        values.resize(2*size);
    }
 
 
    void build(vector<int> &a, int x, int lx, int rx){
        if(rx-lx==1){
            if(lx < (int)a.size()) values[x] = single(a[lx]);
            return;
        }
        int m = (lx+rx)/2;
        build(a,2*x+1,lx,m);
        build(a,2*x+2,m,rx);
        values[x] = merge(values[2*x+1],values[2*x+2]); //change point
    }   
 
    void build(vector<int> &a){
        build(a,0,0,size);
    }
 
    void set(int i, int v, int x, int lx, int rx){
        if(rx-lx == 1){
            values[x] = single(v);
            return;
        }
        int m = (lx+rx)/2;
        if(i<m){
            set(i,v,2*x+1,lx,m);
        }
        else{
            set(i,v,2*x+2,m,rx);
        }
        values[x] = merge(values[2*x+1], values[2*x+2]); // change point
    }
 
    void set(int i, int v){
        set(i,v,0,0,size);
    }
 
    item calc(int l, int r, int x, int lx, int rx){
        if(lx >= r || l>=rx) return NEUTRAL_ELEMENT;
        if(lx>= l && rx<=r) return values[x];
        int m = (lx+rx)/2;
        item s1 = calc(l,r,2*x+1,lx,m);
        item s2 = calc(l,r,2*x+2,m,rx);
        return merge(s1, s2);  //change point
    }
 
    item calc(int l, int r){ //right boundary is excluded!
        return calc(l,r,0,0,size);
    }
 
};
*/
int inv(int i, int m=MOD) {
  return i <= 1 ? i : m - (long long)(m/i) * inv(m % i) % m;
}
 
void display(vi vect) {
    forn(i,(int)vect.size()) {
        cout << vect[i] << ' ';
    }
    cout << "\n";
}
 
vector<int> getPrimes(int n){
    vector<bool> is_prime(n+1, true);
    vi primes;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2; i * i <= n; i++) {
        if (is_prime[i]) {
            for (int j = i * i; j <= n; j += i)
                is_prime[j] = false;
        }
    }
    forn(i,n){
        if(is_prime[i]) primes.pb(i);
    }
    return primes;
}
 
vi vin(int n) {
    vi v;
    forn(i,n) {
        int inpt;
        cin >> inpt;
        v.pb(inpt);
    }
    return v;
}
 
void solve() {
    string a,b,c;
    cin >> a >> b >> c;
    int n = c.length(), l1 = a.length(), l2 = b.length();

    vector<vi> dp(n+1, vi(l1+1,10000));
    /*
        dp  i,j denotes the minimum number of changes for
        making the string upto c[0], ... c[i-1]
        using exactly a[0...j-1]
    */

   dp[0][0] = 0; //the empty string base case;

   //issue: WA on TC2. Starting strings can be empty for one of b/c.

   for(int i = 1; i<=n; i++){
        int mxLen = min(i, l1);
        for(int j = 0; j<=mxLen; j++){   //i is the maxm we can go.
            //case1: using a[j-1] for c[i-1]
            if(j>=0)
            dp[i][j] = min(dp[i][j], dp[i-1][j-1] + (a[j-1] != c[i-1]));

            //case2: not using a[j-1] for c[i-1], means
            // we used a[j-1] before; j from l1, i total => i-j from l2. i-j-1 index is the one.
            if(i-j-1 < l2 && i-j-1 >= 0)
            dp[i][j] = min(dp[i][j], dp[i-1][j] + (b[i-j-1] != c[i-1]));
        }
   }

   cout << dp[n][l1] << en;
}
 
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    int t = 1;
    cin >> t;
    forn(i,t) {
        solve();
    }
}

Submission (verdict: Accepted):
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define forn(i,n) for(int i = 0; i < n; i++)
#define vi vector<int>
#define mii map<int,int>
#define pb push_back
#define en "\n"
#define cyes cout<<"YES\n"
#define cno cout<<"NO\n"
#define int long long
#define pii pair<int, int>
const int N = 1e3+2, MOD = 1e9+7;
/*
struct item{
    int m,c;
};
 
struct segtree{
    int size;
    vector<item> values;
 
    item NEUTRAL_ELEMENT = {INT_MAX, 0}; //change pt
 
    item merge(item a, item b){
        if(a.m < b.m) return a;
        if(b.m < a.m) return b;
        return {a.m, a.c + b.c};
    }
 
    item single(int v){
        return {v,1};
    }
 
    void init(int n) {
        size = 1;
        while(size < n) size *= 2;
        values.resize(2*size);
    }
 
 
    void build(vector<int> &a, int x, int lx, int rx){
        if(rx-lx==1){
            if(lx < (int)a.size()) values[x] = single(a[lx]);
            return;
        }
        int m = (lx+rx)/2;
        build(a,2*x+1,lx,m);
        build(a,2*x+2,m,rx);
        values[x] = merge(values[2*x+1],values[2*x+2]); //change point
    }   
 
    void build(vector<int> &a){
        build(a,0,0,size);
    }
 
    void set(int i, int v, int x, int lx, int rx){
        if(rx-lx == 1){
            values[x] = single(v);
            return;
        }
        int m = (lx+rx)/2;
        if(i<m){
            set(i,v,2*x+1,lx,m);
        }
        else{
            set(i,v,2*x+2,m,rx);
        }
        values[x] = merge(values[2*x+1], values[2*x+2]); // change point
    }
 
    void set(int i, int v){
        set(i,v,0,0,size);
    }
 
    item calc(int l, int r, int x, int lx, int rx){
        if(lx >= r || l>=rx) return NEUTRAL_ELEMENT;
        if(lx>= l && rx<=r) return values[x];
        int m = (lx+rx)/2;
        item s1 = calc(l,r,2*x+1,lx,m);
        item s2 = calc(l,r,2*x+2,m,rx);
        return merge(s1, s2);  //change point
    }
 
    item calc(int l, int r){ //right boundary is excluded!
        return calc(l,r,0,0,size);
    }
 
};
*/
int inv(int i, int m=MOD) {
  return i <= 1 ? i : m - (long long)(m/i) * inv(m % i) % m;
}
 
void display(vi vect) {
    forn(i,(int)vect.size()) {
        cout << vect[i] << ' ';
    }
    cout << "\n";
}
 
vector<int> getPrimes(int n){
    vector<bool> is_prime(n+1, true);
    vi primes;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2; i * i <= n; i++) {
        if (is_prime[i]) {
            for (int j = i * i; j <= n; j += i)
                is_prime[j] = false;
        }
    }
    forn(i,n){
        if(is_prime[i]) primes.pb(i);
    }
    return primes;
}
 
vi vin(int n) {
    vi v;
    forn(i,n) {
        int inpt;
        cin >> inpt;
        v.pb(inpt);
    }
    return v;
}
 
void solve() {
    string a,b,c;
    cin >> a >> b >> c;
    int n = c.length(), l1 = a.length(), l2 = b.length();

    vector<vi> dp(n+1, vi(l1+1,10000));
    /*
        dp  i,j denotes the minimum number of changes for
        making the string upto c[0], ... c[i-1]
        using exactly a[0...j-1]
    */

   dp[0][0] = 0; //the empty string base case;

   //issue: WA on TC2. Starting strings can be empty for one of b/c.

   for(int i = 1; i<=n; i++){
        int mxLen = min(i, l1);
        for(int j = 0; j<=mxLen; j++){   //i is the maxm we can go.
            //case1: using a[j-1] for c[i-1]
            if(j>0)
            dp[i][j] = min(dp[i][j], dp[i-1][j-1] + (a[j-1] != c[i-1]));

            //case2: not using a[j-1] for c[i-1], means
            // we used a[j-1] before; j from l1, i total => i-j from l2. i-j-1 index is the one.
            if(i-j-1 < l2 && i-j-1 >= 0)
            dp[i][j] = min(dp[i][j], dp[i-1][j] + (b[i-j-1] != c[i-1]));
        }
   }

   cout << dp[n][l1] << en;
}
 
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    int t = 1;
    cin >> t;
    forn(i,t) {
        solve();
    }
}