J'ai récemment été confronté à une invite pour un algorithme de programmation que je n'avais aucune idée de quoi faire pour. Je n'ai jamais vraiment écrit d'algorithme auparavant, alors je suis une sorte de nouveaub à cela.
Le problème a dit d'écrire un programme pour déterminer toutes les combinaisons de pièces possibles pour un caissier pour rendre le changement basé sur la pièce de monnaie. valeurs et nombre de pièces de monnaie. Par exemple, il pourrait y avoir une monnaie avec 4 pièces de monnaie: une monnaie de 2 cents, de 6 cents, de 10 cents et de 15 cents. Combien de combinaisons de celles qui sont égales de 50 cents sont là? P>
La langue que j'utilise est C ++, bien que cela ne comporte pas trop de points importants. P>
Edit: Ceci est un Question de programmation plus spécifique, mais comment puis-je analyser une chaîne en C ++ pour obtenir les valeurs de la pièce de monnaie? Ils ont été donnés dans un document texte comme p> (où les chiffres dans ce cas correspondent à l'exemple que j'ai donné) p> p>
13 Réponses :
Une approche plutôt muette est la suivante. Vous construisez une cartographie "pièce de monnaie avec la valeur x est utilisée y fois", puis énumère toutes les combinaisons possibles et sélectionnez uniquement celles qui totalisent la somme souhaitée. Évidemment, pour chaque valeur x, vous devez vérifier y allant de 0 à la somme souhaitée. Ce sera plutôt lent, mais résoudra votre tâche. P>
Quant à la deuxième partie de votre question, supposons que vous ayez cette chaîne dans le fichier maintenant le vecteur coins.txt code>:
monnaie < / code> contiendra les valeurs de pièces possibles. p> p>
Il est très similaire à Le problème du sac à dos p>
Je ne le pense pas. Dans le problème du knapsack, vous essayez de maximiser la valeur, mais dans ce cas, vous n'avez aucune valeur et vous n'essayez pas de maximiser quoi que ce soit, mais de frapper la limite donnée exactement.
Vous devez fondamentalement résoudre l'équation suivante: 50 = A * 4 + B * 6 + C * 10 + D * 15, où les inconnues sont A, B, C, D. Vous pouvez calculer l'instance D = (50 - A * 4-B * 6 - C * 10) / 15 et ainsi de suite pour chaque variable. Ensuite, vous commencez à donner d toutes les valeurs possibles (vous devez commencer par celui qui a les moins valeurs possibles, ici D): 0,1,2,3,4 et que commencer à donner C toutes les valeurs possibles en fonction du courant. valeur de d et ainsi de suite. p>
Ce problème est bien connu sous le nom de problème de changement de monnaie. Veuillez vérifier Ceci et Ceci pour plus de détails. En outre, si Google "Changement de monnaie" ou "changement de monnaie de programmation dynamique", vous obtiendrez de nombreuses autres ressources utiles. p>
Cela semble quelque peu comme une partition, sauf que vous n'utilisez pas tous les entiers dans 1:50. Il semble également semblable au problème de l'emballage des bacs avec de légères différences:
En fait, après y penser, c'est Un ILP , et donc NP -hard. P>
Je suggérerais une programmation dynamique appyoach. Fondamentalement, vous définissez une valeur "reste" et définissez-la sur tout objectif (disons, 50). Ensuite, à chaque étape, vous feriez ce qui suit: p>
Donc, si le reste était de 50 ans et que les plus grandes pièces de monnaie valaient 25 et 10, vous feriez une branche dans deux scénarios: p> la prochaine étape (pour Chaque branche) peut ressembler à: p> Chaque branche se diviserait en deux branches sauf si: p>
Votre description réelle de la façon de résoudre le problème est mort-on, mais il y a quelques problèmes avec le reste: l'approche que vous décrivez n'est pas DP mais la récursion simple (qui est la bonne approche que DP ne nous achèterait rien ici, en supposant que nous Voulez-vous écrire pour écrire en totalité l'ensemble de toutes les solutions). Tout problème de solutions discrètes peut être formulé en tant que ILP - cela n'implique pas la dureté NP. Il n'y a pas de connexion à la bin-emballage que je peux voir.
En fait, je pense que j'ai mal interprété la question - il semble que l'OP veuille savoir que le numéro numéro i> de changement de différentes manières pourrait être apporté. Dans ce cas, DP est effectivement possible et utile: pour chaque combinaison de la taille de la pièce C et de modifier la quantité de valeur A, vous pouvez enregistrer le nombre de façons différentes que possible à l'aide de pièces de taille au plus c. (Une matrice DP 2D est nécessaire pour éviter des solutions à double comptage.)
Trier la liste en arrière: [15 10 6 4 2] P>
Une solution pour 50 ct peut contenir 15 ct ou non. Donc, le nombre de solutions est le nombre de solutions pour 50 ct à l'aide de [10 6 4 2] (ne considérant plus 15 pièces CT) plus fort> le nombre de solutions pour 35 ct (= 50ct - 15ct) en utilisant [15 10 6 4 2]. Répétez le processus pour les deux sous-problèmes. P>
Pour un tel nombre de pièces de monnaie, vous pouvez écrire une solution de force brute simple.
Quelque chose comme ceci: p> une solution de force brute très sale qui imprime tout Combinaisons possibles. P> C'est un problème très célèbre, essayez donc de lire des solutions meilleures que d'autres ont fourni. p> p>
Un algorithme est une procédure de résolution d'un problème, il n'est pas nécessaire que ce soit dans une langue particulière.
Premier éloigne les entrées: p> et les sorties: p> résolvez pour le cas le plus simple que vous pouvez Pensez à d'abord: p> Le résultat doit être: p> Comment résoudriez-vous ce qui précède? P> Que diriez-vous: P> coinTypes = { 1, 2 };
value = { 4 };
results = { [2: 2], [2: 1, 1: 2], [1: 4] }; // the order I put the solutions in is a hint to how to do the algorithm.
Si vous avez des pièces de 15, 10, 6 et 2 centimes et vous devez trouver combien de manières distinctes sont là pour arriver à 50 que vous pouvez
Pour que vous puissiez fondamentalement diviser le problème en des problèmes plus petits (montant éventuellement plus faible et moins de pièces de monnaie). Lorsque vous n'avez qu'un seul type de monnaie, la réponse est bien sûr triviale (vous ne pouvez pas atteindre le montant prescrit exactement ou vous pouvez dans la seule manière possible). P>
En outre, vous pouvez également éviter de répéter le même calcul en utilisant Mémoisation, par exemple, le nombre de manières d'atteindre 20 en utilisant uniquement [6, 2] ne dépend pas si les 30 déjà payés ont été atteints à l'aide de 15 + 15 ou 10 + 10 + 10, de sorte que le résultat du faible problème (20 , [6, 2]) peut être stocké et réutilisé. p>
en Python La mise en œuvre de cette idée est la suivante p>
Voici une solution récursive en Java:
// Usage: int[] denoms = new int[] { 1, 2, 5, 10, 20, 50, 100, 200 }; // System.out.println(ways(denoms, denoms.length, 200)); public static int ways(int denoms[], int index, int capacity) { if (capacity == 0) return 1; if (capacity < 0 || index <= 0 ) return 0; int withoutItem = ways(denoms, index - 1, capacity); int withItem = ways(denoms, index, capacity - denoms[index - 1]); return withoutItem + withItem; }
solution récursive basée sur algorithmist.com ressource dans SCALA:
def countChange(money: Int, coins: List[Int]): Int = { if (money < 0 || coins.isEmpty) 0 else if (money == 0) 1 else countChange(money, coins.tail) + countChange(money - coins.head, coins) }
Une autre version Python:
Cette question a des réponses utiles pour vous; Stackoverflow.com/Questtions/1106929/...
Avez-vous besoin de connaître les combinaisons de pièces réelles ou du nombre d'entre eux?