私は演習としてこの問題に答えようとしています:
ここに{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 RAMで実行しています。大まかな計算では、十分なメモリが必要であることがわかります。
私の計算は間違っていますか?アクセスできるメモリの量は OS によって制限されますか? このソリューションを使用している間に修正できますか?
すべてのフィードバックをお待ちしております。ありがとう。
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;
}
すべてのフィードバックに感謝します