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: 280 ms):
# import sys
# sys.setrecursionlimit(2*(10**3))
# for _ in range(int(input())):
#     a = input()
#     b = input()
#     c = input()
#     dic = {}

#     def calculate(i,j,k,dic):
#         if (i,j,k) in dic:
#             return dic[(i,j,k)]
#         if i == len(a):
#             count = 0
#             while k <len(c):
#                 if c[k] != b[j]:
#                     count+=1
#                 k+=1
#                 j+=1
#             dic[(i,j,k)] = count
#             return count
#         if j == len(b):
#             count = 0
#             while k < len(c):
#                 if c[k] != a[i]:
#                     count+=1
#                 i+=1
#                 k+=1
#             dic[(i,j,k)] = count
#             return count 

#         if c[k]!=a[i] and c[k]!=b[j]:
#             count = 1 + min(calculate(i+1,j,k+1,dic),calculate(i,j+1,k+1,dic))
#         elif c[k]!=a[i] and c[k] == b[j]:
#             count = min(calculate(i,j+1,k+1,dic),calculate(i+1,j,k+1,dic)+1)
#         elif c[k]==a[i] and c[k] != b[j]:
#             count = min(calculate(i,j+1,k+1,dic)+1,calculate(i+1,j,k+1,dic))
#         else:
#             count = min(calculate(i+1,j,k+1,dic),calculate(i,j+1,k+1,dic))

#         dic[(i,j,k)] = count
#         return count    
            
#     print(calculate(0,0,0,dic))

for _ in range(int(input())):
    a = input()
    b = input()
    c = input()

    dp = [[float('inf')] * (len(b) + 1) for _ in range(len(a) + 1)]

    for i in range(len(a) + 1):
        for j in range(len(b) + 1):
            k = i + j
            if k > len(c):
                continue

            if i == 0 and j == 0:
                dp[i][j] = 0
            else:
                if i > 0 and c[k - 1] == a[i - 1]:
                    dp[i][j] = min(dp[i][j], dp[i - 1][j])
                if j > 0 and c[k - 1] == b[j - 1]:
                    dp[i][j] = min(dp[i][j], dp[i][j - 1])
                if i > 0 and c[k - 1] != a[i - 1]:
                    dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1)
                if j > 0 and c[k - 1] != b[j - 1]:
                    dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1)

    print(dp[len(a)][len(b)])