Problem: 2050E - Three Strings
Language: C++23 (GCC 14-64, msys2)

Previous submission (verdict: Time limit exceeded on test 16):
#include <bits/stdc++.h>
using namespace std;

// Function to calculate the minimum changes
int minChanges(const string& a, const string& b, const string& c) {
    int n = a.size(), m = b.size(), p = c.size();

    // Initialize a 2D dp table with dimensions (a.size() + 1) x (b.size() + 1)
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, INT_MAX));
    vector<vector<int>> next(n + 1, vector<int>(m + 1, INT_MAX));

    // Base case: when k == c.size()
    dp[n][m] = 0;

    // Process dp from the end of c to the beginning
    for (int k = p - 1; k >= 0; --k) {
        for (int i = n; i >= 0; --i) {
            for (int j = m; j >= 0; --j) {
                int changes = INT_MAX;

                // Option 1: Take from string a if possible
                if (i < n) {
                    if (a[i] == c[k]) {
                        changes = min(changes, dp[i + 1][j]); // No change
                    } else {
                        changes = min(changes, 1 + dp[i + 1][j]); // One change
                    }
                }

                // Option 2: Take from string b if possible
                if (j < m) {
                    if (b[j] == c[k]) {
                        changes = min(changes, dp[i][j + 1]); // No change
                    } else {
                        changes = min(changes, 1 + dp[i][j + 1]); // One change
                    }
                }

                next[i][j] = changes; // Update the next layer
            }
        }

        // Swap dp and next for the next iteration
        dp.swap(next);
    }

    // The answer is stored in dp[0][0]
    return dp[0][0];
}

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

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

        int result = minChanges(a, b, c);
        cout << result << endl;
    }

    return 0;
}


Submission (verdict: Accepted):
#include <bits/stdc++.h>
using namespace std;

int minChanges(const string& a, const string& b, const string& c) {
    int n = a.size(), m = b.size(), p = c.size();

    // Initialize a 1D DP table with size (b.size() + 1)
    vector<int> dp(m + 1, INT_MAX);
    vector<int> next(m + 1, INT_MAX);

    // Base case: when k == c.size(), no changes are needed
    dp[m] = 0;

    // Process dp from the end of c to the beginning
    for (int k = p - 1; k >= 0; --k) {
        for (int j = m; j >= 0; --j) {
            next[j] = INT_MAX;

            // Option 1: Take from string b
            if (j < m) {
                if (b[j] == c[k]) {
                    next[j] = min(next[j], dp[j + 1]); // No change
                } else {
                    next[j] = min(next[j], 1 + dp[j + 1]); // One change
                }
            }

            // Option 2: Take from string a
            if (k - j < n) {
                if (a[k - j] == c[k]) {
                    next[j] = min(next[j], dp[j]); // No change
                } else {
                    next[j] = min(next[j], 1 + dp[j]); // One change
                }
            }
        }

        // Swap dp and next for the next iteration
        dp.swap(next);
    }

    // The answer is stored in dp[0]
    return dp[0];
}

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

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

        int result = minChanges(a, b, c);
        cout << result << endl;
    }

    return 0;
}