The code you present is very inefficient. For finding the solution for an amount of 63, imagine that it will first recurse to the target amount with steps of the smallest coin (i.e. 1). Then after a lot of backtracking and attempts with other coins, it finally backtracks to the outermost level and tries a coin with value 5. Now the recursion kicks in again, just like before, adding coins of value 1. But the problem is that this intermediate value (63-5) was already visited before (5 levels deep after picking coin 1), and it took a lot of function calls to get results for that value 58. And yet, the algorithm will just ignore that and do all of that work again.
A common solution to this is dynamic programming, i.e. memoizing earlier found solutions so they can be reused without extra work.
I will present here a bottom-up method: it first checks all amounts that can be achieved with just one coin. These amounts are put in a queue. If the target is among them then the answer is 1. If not, all amounts in the queue are processed by adding all possible coins to each of them. Sometimes a value will be found that was already visited before, and in that case it is not put in the next queue, but otherwise it is. If now the target value is in that queue, you know that target can be reached with just 2 coins.
This process continues in a loop, which is in fact just a Breadth-first-search in a tree where amounts are nodes, and edges represent that one amount can be reached from another by adding one coin to it. The search starts in the node that represents an amount of 0.
Here is the code for it:
def rec_coin(target, coins):
visited = set() # Amounts that we have already achieved with a minimal number of coins
amounts = [0] # The latest series of amounts all using an equal number of coins
for min_coins in range(1, target+1):
next_amounts = []
for amount in amounts:
for coin in coins:
added = amount + coin
if added == target:
return min_coins
if not added in visited:
visited.add(added)
next_amounts.append(added)
amounts = next_amounts
print (rec_coin(63,[1,5,10,25]))