I am basically trying to solve the coin change problem through recursion and here is what i have so far -:
#include<iostream>
#include<conio.h>
using namespace std;
int a[]={1,2,5,10,20,50,100,200},count=0;
//i is the array index we are working at
//a[] contains the list of the denominations
//count keeps track of the number of possibilities
void s(int i,int sum) //the function that i wrote
{
if (!( i>7 || sum<0 || (i==7 && sum!=0) )){
if (sum==0) ++count;
s(i+1,sum);
s(i,sum-a[i]);
}
}
int c(int sum,int i ){ //the function that I took from the algorithmist
if (sum == 0)
return 1;
if (sum < 0)
return 0;
if (i <= 0 && sum > 0 )
return 1;
return (c( sum - a[i], i ) + c( sum, i - 1 ));
}
int main()
{
int a;
cin>>a;
s(0,a);
cout<<c(a,7)<<endl<<count;
getch();
return 0;
}
The first function that is s(i,sum) has been written by me and the second function that is c(sum,i) has been taken from here - (www.algorithmist.com/index.php/Coin_Change).
The problem is that count always return a way higher value than expected. However, the algorithmist solution gives a correct answer but I cannot understand this base case
if (i <= 0 && sum > 0 ) return 1;
If the index (i) is lesser than or equal to zero and sum is still not zero shouldn't the function return zero instead of one?
Also I know that the algorithmist solution is correct because on Project Euler, this gave me the correct answer.
I guess that your problem is "Assuming that I have unlimited support of coins, on how many ways can I change the given sum"?
The algoritimists solution you gave assumes also, that the smallest denomination is 1
. Otherwise it will won't work correctly.
Now your question:
if (i <= 0 && sum > 0 ) return 1;
Notice, that the only possibility that i<0
is that you called it with this value - no recursive call will be made with negative value of i
. Such case (i<0
) is an error so no result is proper (maybe assertion or exception would be better).
Now if i=0
, assuming that at index 0
there is coin of value 1
means that there is only one way to exchange sum
with this denomination - give sum
coins of value 1
. Right?
After a moment of thought I found out how to remove assumption that a[0] == 1
. Change
if (i <= 0 && sum > 0 ) return 1;
into
if (i <= 0 && sum > 0 ) return sum % a[0] == 0 ? 1 : 0;