Problem: 2050E - Three Strings
Language: PyPy 3-64

Previous submission (verdict: Time limit exceeded on test 16):
# 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()
    memo = {}

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

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

    
  


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

Submission (verdict: Time limit exceeded on test 15):
# 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()
    memo = [[0 for _ in range(len(c) + 1)] for _ in range(len(a) + 1)]

    @bootstrap
    def dp(i, j, 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 = yield dp(i + 1, j, k + 1)
                
            else:
                vv = yield dp(i + 1, j, k + 1)
                vv += 1
            val = min(val, vv)
               
        if j < len(b):
            if b[j] == c[k]:
                vv = yield dp(i, j + 1, k + 1)
              
            else:
                vv = yield dp(i, j + 1, k + 1)
                vv += 1

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

    
  


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