I went through this question
Number of ways to add up to a sum S with N numbers Find all ways to sum given number (with repetitions allowed) from given set
Did not quite understand the answers there,
I wrote two methods to solve a question:
Find the number of ways you can reach a sum S using numbers N (repetitions allowed)
eg. sum = 4 and numbers = 1,2,3 answer is 1111, 22, 1122, 31 , 13, 1212, 2112, 2212
in One method I use memoization and in the other I do not. Somehow in my machine the memoize version runs WAY slower than the non memoized version
Both of the solutions work.
Memoized Version:
def find_denomination_combinations(amount, denominations):
    memo = {}
    def calculate_combinations(max_amt):
        return_list = list()
        for denomination in denominations:
            new_sum = max_amt - denomination
            if new_sum == 0:
                return_list.append([max_amt])
                return return_list
            elif new_sum < 0:
                return [[]]
            else:
                if new_sum in memo:
                    combi_list = memo[new_sum]
                else:
                    combi_list = calculate_combinations(new_sum)
                for combination in combi_list:
                    if new_sum in memo and combination[:] not in memo[new_sum]:
                        memo[new_sum].append(combination[:])
                    else:
                        memo[new_sum] = []
                        memo[new_sum].append(combination[:])
                    combination.append(denomination)
                    return_list.append(combination)
        return return_list
    result = calculate_combinations(amount)
    return result
Non Memoized Version
def find_denomination_combinations_nmemo(amount, denominations):
    def calculate_combinations(max_amt):
        return_list = list()
        for denomination in denominations:
            new_sum = max_amt - denomination
            if new_sum == 0:
                return_list.append([max_amt])
                return return_list
            elif new_sum < 0:
                return [[]]
            else:
                combi_list = calculate_combinations(new_sum)
                for combination in combi_list:
                    combination.append(denomination)
                    return_list.append(combination)
        return return_list
    result = calculate_combinations(amount)
    return result
My algorithm is :
[T(sum-D)] for each D where D belongs to given set of integers
If input sum = 16 and set of integers = [1,2,3]
Non memoized version runs in 0.3 seconds , memoized version takes 5 seconds