Problem: 2050E - Three Strings
Language: python

Solution 1 (runtime: 1202 ms):
# author 
# Kidus Guade

import sys
import random
from types import GeneratorType
from sys import stdin,stdout
from math import gcd,floor,sqrt,log, ceil
from collections import defaultdict, Counter, deque
from bisect import bisect_left,bisect_right, insort_left, insort_right
def ints(): return map(int, sys.stdin.readline().strip().split())
def li(): return list(map(int, sys.stdin.readline().strip().split()))
def string(): return sys.stdin.readline().strip()
def get_int(): return int(sys.stdin.readline().strip())
def li_strings(): return list(map(str, sys.stdin.readline().strip().split()))


def bootstrap(f, 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 primeFactors(n):
    
    i = 2
    primfac = []
    while i * i <= n:
        while n % i == 0:
            primfac.append(i)
            n = n / i
        i = i + 1
    if n > 1:
        primfac.append(int(n))
    return primfac
def prime_sieve(n):
    is_prime = [True for _ in range(n + 1)]
    is_prime[0] = is_prime[1] = False
    i = 2
    while i * i <= n:
        if is_prime[i]:
            j = i * i
            while j <= n:
                is_prime[j] = False
                j += i
        i += 1
    return is_prime
def find_divisors(number):
    divisors = []
    for i in range(1, int(number**0.5) + 1):
        if number % i == 0:
            divisors.append(i)
            if i != number // i:
                divisors.append(number // i)
    return divisors    
def solve():
    a = string()
    b = string()
    c = string()
    dp = [[float("inf") for _ in range(len(a) + 1)] for _ in range(len(c) + 1)]
    for i in range(len(a) + 1):
        dp[len(c)][i] = 0
  
    for i in range(len(c) -1, -1, -1):
        for j in range(len(a) + 1):
            if j > i:
                continue
            k = i - j
           
            vv1, vv2= float("inf"), float("inf")
            if j  < len(a):
                if a[j] == c[i]:
                    vv1 = dp[i + 1][j +1]
                else:
                    vv1 = 1 + dp[i + 1][j + 1]
            if k < len(b):
                if b[k] == c[i]:
                    vv2 = dp[i + 1][j]
                else:
                    vv2 = 1 + dp[i + 1][j]
            
            dp[i][j] = min(min(vv1, vv2), dp[i][j])
    return dp[0][0]
    a = string()
    b = string()
    c = string()

    

   
    memo = [[float('inf') for _ in range(len(c) + 1)] for _ in range(len(a) + 1)]
    
 
    for i in range(len(a) + 1):
        memo[i][len(c)] = 0

  
    for k in range(len(c) - 1, -1, -1):
        for i in range(len(a) + 1):
            if i < len(a):
                if a[i] == c[k]:
                    vv = memo[i + 1][k + 1]
                else:
                    vv = 1 + memo[i + 1][k + 1]
                memo[i][k] = min(memo[i][k], vv)

            if k - i < len(b):
                if b[k - i] == c[k]:
                    vv = memo[i][k + 1]
                else:
                    vv = 1 + memo[i][k + 1]
                memo[i][k] = min(memo[i][k], vv)

    # The result is stored in memo[0][0]
    return memo[0][0]
    
    

# Call the solve function
# result = solve()
# print(result)
    
        
                



    
    # return dp[len(a)][len(c)]

   

    memo = [[0 for _ in range(len(c) + 1)] for _ in range(len(a) + 1)]
    def dp(i,k):
        if k == len(c):
            yield 0
        if memo[i][k]:
            yield memo[i][k]
        val = float('inf')
        if i < len(a):
            if a[i] == c[k]:
                vv = dp(i + 1,k + 1)
                
            else:
                vv = dp(i + 1,k + 1)
                vv += 1
            val = min(val, vv)
               
        if k - i < len(b):
            if b[k - i ] == c[k]:
                vv = dp(i,  k + 1)
              
            else:
                vv = dp(i, k + 1)
                vv += 1

            val = min(val, vv)
        memo[i][k] = val
        yield memo[i][k]
    return dp(0,0)

    
  


    
    
    
if __name__ == "__main__":
    for _ in range(get_int()):
        print(solve())

Solution 2 (runtime: 234 ms):
from functools import *
from itertools import *
from collections import *
from math import *
from bisect import *
from heapq import *

def factors(n):
    i = 1
    res = []
    while i <= sqrt(n):
        if (n % i == 0):
            if (n / i == i):
                res.append(i)
            else:
                res.append(i)
                res.append(n//i)
        i = i + 1
    return res

def prime_factors(n):
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return factors

def largest_prime_factor(n):
    i = 2
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
    return n

def sieve(n):
    prime = [True for i in range(n+1)]
    p = 2
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * p, n+1, p):
                prime[i] = False
        p += 1

    return prime

MOD=10**9+7
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]
 
    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]
 
    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]
 
    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]
 
class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)
 
    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

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

    mask = 0

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

    for ai in range(len(a), -1, -1):
        for bi in range(len(b), -1, -1):
            i = ai+bi
            if i>=len(c):
                dp[ai][bi] = 0
                continue
            
            ago = inf
            bgo = inf

            if ai<len(a):
                ago = int(a[ai]!=c[i]) + dp[ai+1][bi]
            if bi<len(b):
                bgo = int(b[bi]!=c[i]) + dp[ai][bi+1]
            dp[ai][bi] = min(ago, bgo)
    print(dp[0][0])