forked from menault/2026_TD3_DEV51_Qualite_Algo
Optimiser F8 avec un tableau de programmation dynamique
This commit is contained in:
@@ -331,3 +331,20 @@ paires sur les **97 655 tableaux** de longueur 1 à 7 à montants dans
|
|||||||
`[-2, 2]`, ainsi que sur une entrée vide. Ils vérifient aussi que les
|
`[-2, 2]`, ainsi que sur une entrée vide. Ils vérifient aussi que les
|
||||||
transactions d'origine restent inchangées, notamment en présence de
|
transactions d'origine restent inchangées, notamment en présence de
|
||||||
doublons et de plusieurs zéros.
|
doublons et de plusieurs zéros.
|
||||||
|
|
||||||
|
### F8 — Programmation dynamique pour le rendu de monnaie
|
||||||
|
|
||||||
|
`facons[s]` contient le nombre de façons de rendre `s` avec les pièces déjà
|
||||||
|
traitées. Il vaut initialement 1 pour la somme nulle et 0 ailleurs. Pour
|
||||||
|
chaque pièce, les sommes sont parcourues dans l'ordre croissant et l'on
|
||||||
|
ajoute `facons[s - piece]` à `facons[s]`. Ce sens permet la réutilisation
|
||||||
|
d'une pièce ; la boucle des pièces à l'extérieur compte des combinaisons,
|
||||||
|
sans distinguer l'ordre des pièces.
|
||||||
|
|
||||||
|
Chaque état est calculé une seule fois par type de pièce : **`O(S × k)`**
|
||||||
|
pour `k ≥ 1` (et `O(S × k + S)` en incluant l'initialisation si `k = 0`),
|
||||||
|
avec **`O(S)`** de mémoire. La récursion et ses sous-problèmes répétés
|
||||||
|
disparaissent. F8 passe de **M = 4 à M = 5** : l'amélioration temporelle
|
||||||
|
n'implique pas une baisse de M. Les tests comparent les résultats à la
|
||||||
|
récursion initiale pour les sommes de -2 à 40 et de 0 à 8 types de pièces,
|
||||||
|
y compris la somme nulle et l'absence de pièces.
|
||||||
|
|||||||
@@ -242,12 +242,20 @@ static const int PIECES[] = {1, 2, 5, 10, 20, 50, 100, 200};
|
|||||||
|
|
||||||
long nb_facons_rendre(int somme, int nb_pieces)
|
long nb_facons_rendre(int somme, int nb_pieces)
|
||||||
{
|
{
|
||||||
if (somme == 0)
|
if (somme < 0)
|
||||||
return 1;
|
|
||||||
if (somme < 0 || nb_pieces == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
return nb_facons_rendre(somme - PIECES[nb_pieces - 1], nb_pieces) +
|
long *facons = calloc((size_t)somme + 1, sizeof(*facons));
|
||||||
nb_facons_rendre(somme, nb_pieces - 1);
|
if (facons == NULL) {
|
||||||
|
perror("Allocation du tableau de rendu de monnaie");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
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) */
|
/* F9 : catégorie d'une transaction (pour les statistiques) */
|
||||||
|
|||||||
@@ -207,6 +207,23 @@ static void tester_paires(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long monnaie_reference(int somme, int nb_pieces)
|
||||||
|
{
|
||||||
|
if (somme == 0)
|
||||||
|
return 1;
|
||||||
|
if (somme < 0 || nb_pieces == 0)
|
||||||
|
return 0;
|
||||||
|
return monnaie_reference(somme - PIECES[nb_pieces - 1], nb_pieces) +
|
||||||
|
monnaie_reference(somme, nb_pieces - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tester_monnaie(void)
|
||||||
|
{
|
||||||
|
for (int s = -2; s <= 40; s++)
|
||||||
|
for (int k = 0; k <= NB_PIECES; k++)
|
||||||
|
assert(nb_facons_rendre(s, k) == monnaie_reference(s, k));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
tester_tri();
|
tester_tri();
|
||||||
@@ -216,6 +233,7 @@ int main(void)
|
|||||||
tester_periodes();
|
tester_periodes();
|
||||||
tester_recherches();
|
tester_recherches();
|
||||||
tester_paires();
|
tester_paires();
|
||||||
|
tester_monnaie();
|
||||||
puts("Tests banque : OK");
|
puts("Tests banque : OK");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user