Coin change

Coin Change is the problem of finding the number of ways of making changes for a particular amount of cents, $$n$$, using a given set of denominations $$d_1 \ldots d_m$$. It is a general case of Integer Partition, and can be solved with dynamic programming.

Overview
The problem is typically asked as: If we want to make change for $$n$$ cents, and we have infinite supply of each of $$S = \{ S_1, S_2, \ldots, S_m \}$$ valued coins, how many ways can we make the change? (For simplicity's sake, the order does not matter.)

It is more precisely definedas:

Given an integer $$N$$ and a set of integers $$S = \{ S_1, S_2, \ldots, S_m \}$$, how many ways can one express $$n$$ as a linear combination of $$S = \{ S_1, S_2, \ldots, S_m \}$$ with non-negative coefficients?

Mathematically, how many solutions are there to $$N = \sum_{k = 1 \ldots m}{ x_k S_k }$$ where $$x_k \geq 0, k \in \{ 1 \ldots m \} $$

For example, for $$n = 4, S = \{1, 2, 3\}$$, there are four solutions: $$\{1, 1, 1, 1\}, \{1, 1, 2\} , \{2, 2\} , \{1, 3\}$$.

Recursive formulation
We define a particular solution to the question to be a set, in the above example, {1,1,1,1} is a solution, and {2,2} is another solution, for n=4, S={1,2,3}.

We are trying to count the number of distinct sets.

Since order does not matter, we will impose that our solutions (sets) are all sorted in non-decreasing order (Thus, we are looking at sorted-set solutions: collections).

Now, for a particular n and S[1..m] = {S[1],S[2],...,S[m]} (again, we impose that S[1]<S[2]<...<S[m], so that our solutions can be constructed in non-decreasing order), the set of solutions for this problem, P[n][m], can be partitioned:


 * There are those sets that does not contain any S[m],
 * and those sets that contain at least 1 S[m],

If a solution does not contain S[m], we are actually making change for n without S[m](using only S[1..m-1]), this partition are solutions of P[n][m-1].

If a solution contains S[m], then we know we are using at least 1 S[m] in our change, resulting in n-S[m] amount of cents left to be changed. Thus, this partition are solutions of P[n-S[m]][m].

In conclusion

P[n][m]=P[n][m-1]+P[n-S[m]][m].

P[n=0][m] = 1.

P[n<0][m] = 0.

P[n>=1][m<=0] = 0.

Dynamic programming
Note that the recursion satisfies the weak ordering R(n,m) < R(x,y) iff n<=x and m<=y and (n,m)!=(x,y). This as a result satisfies The optimal-substructure property of dynamic programming.

Thus, the result can be computed in O(nm) time.

A good solution to this problem can be found here