F8 : rendu de monnaie par programmation dynamique (O(S × k))

La récursion naïve recalculait les mêmes sous-problèmes : 266 723 739
appels pour rendre 400 centimes avec 8 pièces. Le tableau facons[0..S],
mis à jour pièce par pièce, compte les mêmes combinaisons en S × k
additions (3 200 ici).

Temps (-O2) : 1,17 s → 1,00 s. En -O0 -pg, le surcoût de _mcount
(16,2 s) disparaît avec les appels récursifs. Empreinte inchangée
(ff68d260a7a58441).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 10:53:24 +02:00
parent cb7857cd43
commit d19085ed45
+10 -6
View File
@@ -171,14 +171,18 @@ long nb_paires_opposees(const Transaction *t, int n)
static const int PIECES[] = {1, 2, 5, 10, 20, 50, 100, 200};
#define NB_PIECES 8
/* Programmation dynamique : après avoir traité les p premières pièces,
* facons[s] est le nombre de façons de rendre s avec ces pièces. */
long nb_facons_rendre(int somme, int nb_pieces)
{
if (somme == 0)
return 1;
if (somme < 0 || nb_pieces == 0)
return 0;
return nb_facons_rendre(somme - PIECES[nb_pieces - 1], nb_pieces) +
nb_facons_rendre(somme, nb_pieces - 1);
long *facons = calloc(somme + 1, sizeof(long));
facons[0] = 1;
for (int p = 0; p < nb_pieces; p++)
for (int s = PIECES[p]; s <= somme; s++)
facons[s] += facons[s - PIECES[p]];
long resultat = facons[somme];
free(facons);
return resultat;
}
/* F9 : catégorie d'une transaction (pour les statistiques) */