Decomposing a number as a sum of two products using tree recursion
First try to solve without a helper function. Also try to solve using a helper function and adding up to the sum.


You haven't included an implementation without a helper function.
You implemented memoization, which was not part of the description.
In any case, memoization won't be possible without a helper function or annotations.

Code review

There are several problems with your implementation:


memoiz shouldn't be a list, but a set
The value variable is confusing: it merely stores the original values of n1 and n2, you could simply save those values before calling the helper function
sum is a poor name for a variable, because it shadows the built-in named "sum"
There should be spaces around operators to improve readability, for example instead of (x+1)*value[0] it should be (x + 1) * value[0]
Instead of multiplying value[0] and value[1], it would be better to accumulate a sum
If result1 is True, there's no need to evaluate result2


With the above tips, the solution can be simplified a bit and become more efficient:

memoiz = set()
def has_sum(sum, n1, n2, x=0, y=0):
    if n1 + n2 == sum:
        return True
    if n1 + n2 &gt; sum:
        return False
    if (x+1, y) not in memoiz:
        memoiz.add((x+1, y))
        result1 = has_sum(sum, n1 + orig_n1, n2, x+1, y)
        if result1:
            return True
    if (x, y+1) not in memoiz:
        memoiz.add((x, y+1))
        return has_sum(sum, n1, n2 + orig_n2, x, y+1)
    return False
orig_n1, orig_n2 = n1, n2
return has_sum(sum, 0, 0)


An alternative solution

Consider this alternative algorithm:


If target is 0, then we can reach it by 0 times n1 and n2
If target is below 0, then we cannot reach it
If target can be reached by a sum of multiples of n1 and n2,
then target - n1 or target - n2 must be reachable too


Implementation using memoization:

memoize = { 0: True }
def helper(target):
    if target not in memoize:
        if target &lt; 0:
            memoize[target] = False
        else:
            memoize[target] = helper(target - n1) or helper(target - n2)
    return memoize[target]
return helper(target)


Iterative solution

At first I overlooked your requirement of a recursive solution.
For the record, this was my original suggestion using iterative logic.



Unless I'm missing something,
you can solve this using a much simpler algorithm:


If a solution exists, then sum == n1 * A + n2 * B where A and B are integers
Loop from A = 0 to sum, by steps of n1
If sum - A is divisible by n2, then a solution exists
If the end of the loop is reached, then a solution doesn't exist


That is:

for A in range(0, sum + 1, n1):
    if (sum - A) % n2 == 0:
        return True
return False