Combine String - Dynamic Programming / Interval

https://algo.monster/problems/combine_string

I understand the intention of teaching DP here, I just feel like the DP solution for this problem is overcomplicated and worse than just not using DP and using 3 pointers instead such as this:

def combine_string(s1: str, s2: str, s3: str) → bool:
n1,n2,n3 = len(s1),len(s2),len(s3)
if (n1+n2 != n3):
return False

i,j,k=n1-1,n2-1,n3-1

while k >= 0:
    if i>=0 and s1[i] == s3[k]:
        k-=1
        i-=1
    elif j>=0 and s2[j] == s3[k]:
        j-=1
        k-=1
    else:
        return False
return True

The below non-DP solutions may not work for certain use cases, when both the conditions (i>=0 and s1[i] == s3[k]) and (j>=0 and s2[j] == s3[k]) are true at the same time.

this works only for strings with distinct chars

Easily understandable
Dp solution which same as recursion:

if len(s1) + len(s2) != len(s3):
        return False
    dp =[[False]*(len(s2)+1) for i in range(len(s1)+1)]
    #print(dp)
    dp[len(s1)][len(s2)] = True
    for i in range(len(s1), -1, -1):
        for j in range(len(s2), -1, -1):
            if i < len(s1) and s1[i] == s3[i+j] and dp[i+1][j]:
                dp[i][j] = True
            if j < len(s2) and s2[j] == s3[i+j] and dp[i][j+1]:
                dp[i][j] = True
    return dp[0][0]

Recursion Solution:

if len(s1) + len(s2) != len(s3):
        return False
dp  ={}
    def dfs(i, j):
        if i == len(s1) and j == len(s2):
             return True
        if (i,j) in dp:
            return dp[(i, j)]
        if i < len(s1) and s1[i] == s3[i+j] and dfs(i+1, j):
            return True
        if j < len(s2) and s2[j] == s3[i+j] and dfs(i, j+1):
            return True
        dp[(i,j)] = False
        return False
    return dfs(0,0)

I don’t understand. What is wrong with s1 + s2?