I am trying to answer this problem as an exercise:
Here are coins from {50,25,10,5,1} cents in the box. Write a program to find the number of ways to create 1 dollar by grouping coins.
My solution involves creating a tree with each edge having one of the values above. Each node will hold the amount of coins. I could then fill this tree and look for leaves that are up to 100. So here is my code
class TrieNode { public: TrieNode(TrieNode* Parent=NULL,int sum=0,TrieNode* FirstChild=NULL,int children=0, bool key =false ) :pParent(Parent),pChild(FirstChild),isKey(key),Sum(sum),NoChildren(children) { if(Sum==100) isKey=true; } void SetChildren(int children) { pChild = new TrieNode[children](); NoChildren=children; } ~TrieNode(void); //pointers TrieNode* pParent; TrieNode* pChild; int NoChildren; bool isKey; int Sum; }; void Populate(TrieNode* Root, int coins[],int size) { //Set children Root->SetChildren(size); //add children for(int i=0;i<size;i++) { TrieNode* child = &Root->pChild[0]; int c = Root->Sum+coins[i]; if(c<=100) { child = new TrieNode(Root,c); if(!child->isKey) //recursively populate if not a key Populate(child,coins,size); } else child = NULL; } } int getNumKeys(TrieNode* Root) { int keys=0; if(Root == NULL) return 0; //increment keys if this is a key if(Root->isKey) keys++; for(int i=0; i<Root->NoChildren;i++) { keys+= getNumKeys(&Root->pChild[i]); } return keys; } int _tmain(int argc, _TCHAR* argv[]) { TrieNode* RootNode = new TrieNode(NULL,0); int coins[] = {50,25,10,5,1}; int size = 5; Populate(RootNode,coins,size); int combos = getNumKeys(RootNode); printf("%i",combos); return 0; }
The problem is that the tree is so large that after a few seconds the program crashes. I run this on windows 7, a quad core, with 8 GB of RAM. A rough calculation tells me that I should have enough memory.
Are my calculations wrong? Does the OS limit the amount of memory that I have access to? Can I fix this while still using this solution?
All reviews are welcome. Thanks.
Edit1: I confirmed that the above approach is incorrect. Trying to build a tree with a set of 1 coin. coins [] = {1};
I found that the algorithm still does not work. After reading a post from Lenik and from João Menigin, I came up with this solution that combines both ideas together to make a recursive solution that accepts any array size
//N is the total the coins have to amount to int getComobs(int coins[], int size,int N) { //write base cases //if array empty | coin value is zero or N is zero if(size==0 || coins[0]==0 ||N==0) return 0; int thisCoin = coins[0]; int atMost = N / thisCoin ; //if only 1 coin denomination if(size==1) { //if all coins fit in N if(N%thisCoin==0) return 1; else return 0; } int combos =0; //write recursion for(int denomination =0; denomination<atMost;denomination++) { coins++;//reduce array ptr combos+= getComobs(coins, size-1,N-denomination*thisCoin); coins--;//increment array ptr } return combos; }
Thanks for all the feedback.