我试图作为练习来回答这个问题:
这里有一组 {50,25,10,5,1} 美分的硬币放在一个盒子里。编写一个程序,找出通过对硬币分组来创建 1 美元的方法的数量。
我的解决方案包括制作一棵树,每条边都具有上述值之一。然后每个节点将持有硬币的总和。然后我可以填充这棵树并查找加起来为 100 的叶子。所以这是我的代码
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;
}
问题是树太大了,几秒钟后程序就崩溃了。我在 Windows 7、四核、8gb 内存上运行它。粗略的计算告诉我我应该有足够的内存。
我的计算不正确吗?操作系统是否限制我可以访问的内存量?我可以在仍然使用此解决方案的同时修复它吗?
感谢所有反馈。谢谢。
Edit1: 我已经验证上述方法是错误的。通过尝试用一组只有 1 个硬币构建一棵树。硬币[] = {1};
我发现算法仍然失败。在阅读了 Lenik 和 João Menighin 的帖子后,我想出了这个解决方案,它将两个想法联系在一起,形成一个递归解决方案,它可以采用任何大小的数组
//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;
}
感谢所有的反馈