11
votes

Algorithme pour déterminer les combinaisons de pièces

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à?

La langue que j'utilise est C ++, bien que cela ne comporte pas trop de points importants.

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 xxx

(où les chiffres dans ce cas correspondent à l'exemple que j'ai donné)


2 commentaires

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?


13 Réponses :


0
votes

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.


0 commentaires

1
votes

Quant à la deuxième partie de votre question, supposons que vous ayez cette chaîne dans le fichier coins.txt : xxx

maintenant le vecteur monnaie < / code> contiendra les valeurs de pièces possibles.


0 commentaires

0
votes

Il est très similaire à Le problème du sac à dos


1 commentaires

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.



0
votes

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.


0 commentaires

7
votes

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.


0 commentaires

6
votes

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:

  • wikipedia: partition (théorie des nombres)
  • Wikipedia: Bin Emballage Problème
  • Wolfram Mathworld: Partion

    En fait, après y penser, c'est Un ILP , et donc NP -hard.

    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:

    1. Découvrez quelle est la plus grande pièce de monnaie pouvant accueillir dans le reste
    2. considère ce qui se passerait si vous (a) inclus que la pièce ou (b) n'incluait pas cette pièce de monnaie.
    3. pour chaque scénario, recueil.

      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: xxx

      la prochaine étape (pour Chaque branche) peut ressembler à: xxx

      Chaque branche se diviserait en deux branches sauf si:

      • Le reste était de 0 (auquel cas vous le connecteriez)
      • Le reste était inférieur à la plus petite pièce (auquel cas vous le rejeteriez)
      • Il ne restait plus de pièces de monnaie (auquel cas vous le supprimez depuis le reste! = 0)

2 commentaires

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 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.)



0
votes

Trier la liste en arrière: [15 10 6 4 2]

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 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.


0 commentaires

1
votes

Pour un tel nombre de pièces de monnaie, vous pouvez écrire une solution de force brute simple.

Quelque chose comme ceci: xxx

une solution de force brute très sale qui imprime tout Combinaisons possibles.

C'est un problème très célèbre, essayez donc de lire des solutions meilleures que d'autres ont fourni.


0 commentaires

0
votes

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> xxx pré>

et les sorties: p> xxx pré>

résolvez pour le cas le plus simple que vous pouvez Pensez à d'abord: p> xxx pré>

Le résultat doit être: p> xxx pré>

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.


0 commentaires

4
votes

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

  • comptez le nombre de moyens distincts que vous devez atteindre 50 en utilisant seulement 10, 6 et 2
  • comptez combien de façons distincts vous devez atteindre 50-15 en utilisant seulement 10, 6 et 2
  • comptez le nombre de moyens distincts que vous devez atteindre 50-15 * 2 en utilisant seulement 10, 6 et 2
  • comptez combien de moyens distincts vous devez atteindre 50-15 * 3 en utilisant seulement 10, 6 et 2
  • résumer tous ces résultats qui sont bien sûr distincts (dans la première fois, je n'ai utilisé aucune pièce de monnaie 15C, dans la seconde que j'utilisais un, dans les deux troisièmes et au quatrième trois).

    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).

    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é.

    en Python La mise en œuvre de cette idée est la suivante xxx


0 commentaires

7
votes

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;
}


0 commentaires

0
votes

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)
}


0 commentaires

0
votes

Une autre version Python: xxx


0 commentaires