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?