There are solutions to this problem already posted, so I'll assume you're asking about how to think about it, not for the answer itself.
Try this:
Let V be the target value.
Let C[i] be the i'th coin value.
Recursive solutions are about making a choice that reduces the size of problem, then recursively using the same solution on the smaller problem.
When the problem is small enough to solve easily without recurring, we just return that solution. This is the "base case."
Here the choice is to use a specific number N[i] of coins with value C[i].
We need to to this for all possible values of N[i], i.e. N[i] = 0,1,2,...floor(V/C[i]). The integer floor(V/C[i]) is just the maximum number of i'th coins that might produce correct change.
Once we've made a choice of how many i'th coins to use, we shouldn't change that decision. (This is where your solution goes wrong.) The simplest way to do this is to exploit the implicit order of coins due to their array indices. We recursively find the number of ways to make change using coins i+1 and larger for the remaining part of the target value: V - N[i] * coins[i].
(An alternative design would be to maintain the coins in a set and make the choice by removing coin[i] from the set before recurring. But let's stay with the indices because the resulting code is simpler.)
To produce the result, we just add up all the recursively determined counts.
With that thinking, we can choose a signature for the recursive method:
/**
* Return the number of ways to make change for the given value
* using coins i >= iMin.
*/
int count(int value, int iMin);
Time to think about bases cases. "Success" is when value
is exactly zero: we can make change in exactly 1 way by doing exactly nothing! "Failure" occurs when value
isn't zero, and we're out of coin values to try. This is just when iMin
has reached the length of the coins
array.
Let's put this thinking into code:
int count(int value, int iMin) {
if (value == 0) return 1; // Success base case.
if (iMin >= coins.length) return 0; // Failure base case.
result = 0;
for (int ni = 0; ni <= value / coins[iMin]; ++ni)
result += count(value - ni * coins[iMin], iMin + 1);
return result;
}
To start the recursion, just use the target value and iMin
of zero:
int result = count(target, 0);
Note that though this solution is correct, it isn't so efficient. Let's leave that discussion for another day.