Problem: 2050E - Three Strings
Language: python

Solution 1 (runtime: 265 ms):
import sys, random, math, string, itertools
from copy import deepcopy
from collections import defaultdict, Counter, deque
from heapq import heapify, heappush, heappop
from functools import cache
from bisect import bisect_left, bisect_right
from types import GeneratorType
from typing import *

input = lambda: sys.stdin.readline().strip()


def debug(*x, **y):
    if not DEBUG_ENABLED:
        return
    print(*x, (y if y != {} else "\b"), file=sys.stderr)


###############################################################################


def solve_bruteforce(case=None):
    pass


def execute_once():
    pass

def solve(case=None):
    a,b,c = input(),input(),input()

    # @cache
    # def dp(i,j):
    #     ind = i+j 

    #     if ind == len(c):
    #         return 0
        
    #     ch = c[ind]

    #     return min(
    #         (dp(i+1,j) + (1 if a[i] != ch else 0) ) if i < len(a) else math.inf,
    #         (dp(i,j+1) + (1 if b[j] != ch else 0) ) if j < len(b) else math.inf
    #     )

    n,m = len(a),len(b)

    dp = [[math.inf]*(m+1) for _ in range(n+1)]
    dp[-1][-1] = 0

    for i in range(n,-1,-1):
        for j in range(m,-1,-1):
            if i+j == len(c):
                continue

            ch = c[i+j]

            if i < n:
                dp[i][j] = min(dp[i][j], dp[i+1][j] + (1 if a[i] != ch else 0))
            if j < m:
                dp[i][j] = min(dp[i][j], dp[i][j+1] + (1 if b[j] != ch else 0))
    
    # for i in dp:
    #     print(i)

    ans = dp[0][0]
    print(ans)


INPUT_NUMBER_OF_TEST_CASES = 1
SKIP_SOLVE = 0
DEBUG_ENABLED = 1
MOD = 10**9 + 7
BOOLEAN_RETURN = 0
TRUE_MAPPING, FALSE_MAPPING = "YES", "NO"

###############################################################################


class CustomHashMap:
    def __init__(self, map_type=dict, arg=None):
        """
        Custom HashMap for Python's Anti-hash-table test
        :param map_type: type of the map (allowed types: dict, defaultdict, Counter)
        :param arg: argument for the map (should be list if map_type is Counter and function if map_type is defaultdict)
        """
        self.RANDOM = random.randrange(2**62)
        if map_type == Counter:
            self.dict = map_type([self.wrapper(i) for i in arg])
        elif map_type == defaultdict:
            self.dict = map_type(arg)
        else:
            self.dict = map_type()

    def wrapper(self, num):
        return num ^ self.RANDOM

    def __setitem__(self, key, value):
        self.dict[self.wrapper(key)] = value

    def __getitem__(self, key):
        return self.dict[self.wrapper(key)]

    def __contains__(self, key):
        return self.wrapper(key) in self.dict

    def __iter__(self):
        return iter(self.wrapper(i) for i in self.dict)

    def keys(self):
        return [self.wrapper(i) for i in self.dict]

    def values(self):
        return [i for i in self.dict.values()]

    def items(self):
        return [(self.wrapper(i), j) for i, j in self.dict.items()]

    def __repr__(self):
        return repr({self.wrapper(i): j for i, j in self.dict.items()})


def recursion_limit_fix(f):
    """
    recursion limit fix decorator, change 'return' to 'yield' and add 'yield' before calling the function
    and add 'yield' after the function if not returning anything
    """
    stack = []

    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc


def binary_search(left, right, check, start_from_left):
    if start_from_left:
        ans = left
    else:
        ans = right
    while left <= right:
        mid = (left + right) // 2
        if start_from_left:
            if check(mid):
                ans, left = mid, mid + 1
            else:
                right = mid - 1
        else:
            if check(mid):
                ans, right = mid, mid - 1
            else:
                left = mid + 1
    return ans


execute_once()

if not SKIP_SOLVE:
    for t in range(int(input()) if INPUT_NUMBER_OF_TEST_CASES else 1):
        if BOOLEAN_RETURN:
            print(TRUE_MAPPING if solve(t + 1) else FALSE_MAPPING)
        else:
            solve(t + 1)


Solution 2 (runtime: 2390 ms):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10000)

############ ---- Input Functions ---- ############
def inp():
    return(int(input()))
def inlt():
    return(list(map(int,input().split())))
def insr():
    s = input()
    return(list(s[:len(s) - 1]))
def invr():
    return(map(int,input().split()))


def count_changes(a, b, c, i, j, k, memo_arr):
    if memo_arr[i][j] == -1:
        if k == len(c):
            memo_arr[i][j] = 0
        elif i == len(a):
            ans = 0
            for count in range(len(b[j:])):
                if b[j + count] != c[k+count]:
                    ans += 1
            memo_arr[i][j] = ans
        elif j == len(b):           
            ans = 0
            for count in range(len(a[i:])):
                if a[i + count] != c[k+count]:
                    ans += 1
            memo_arr[i][j] = ans
        else:
            case1 = count_changes(a, b, c, i+1, j, k+1, memo_arr)
            if a[i] != c[k]:
                case1 += 1
            case2 = count_changes(a, b, c, i, j+1, k+1, memo_arr)
            if b[j] != c[k]:
                case2 += 1
            memo_arr[i][j] = min(case1, case2)
    
    return memo_arr[i][j]


t = inp()
for _ in range(t):
    a = insr()
    b = insr()
    c = insr()

    i = 0
    j = 0

    k = 0
    memo_arr = [[-1 for _ in range(len(b)+1)] for _ in range(len(a) + 1)]
    print(count_changes(a, b, c, i, j, k, memo_arr))