Un cap pour ce chapitre
Ce que vous saurez faire
- Définir un état et une récurrence.
- Construire une table de résultats dans le bon ordre.
- Retrouver une solution optimale et discuter la mémoire.
Les bases utiles pour commencer
Nommer exactement le sous-problème
Notons C(s) le nombre minimal de pièces nécessaires pour former la somme entière s, avec un stock illimité de chaque valeur autorisée. C(0)=0 : aucune pièce n’est nécessaire. Pour s positif, on essaie chaque dernière pièce p qui ne dépasse pas s, puis on considère 1+C(s-p).
La meilleure valeur est le minimum de ces possibilités. Si aucune combinaison ne forme s, on conserve un marqueur inaccessible. Cette définition de l’état est essentielle : C(s) ne représente ni la valeur des pièces choisies, ni une liste de solutions, mais un nombre minimal. Une table auxiliaire peut ensuite conserver un choix pour reconstruire une solution.
La récurrence est justifiée en retirant une dernière pièce d’une solution optimale. Le reste doit lui-même utiliser un nombre minimal de pièces pour sa somme : sinon on pourrait le remplacer par une meilleure solution et améliorer le total. Cette propriété explique pourquoi les sous-résultats suffisent à construire un optimum global.
Calculer dans l’ordre des dépendances
Avec les pièces 4,3,1, on obtient C(0)=0, C(1)=1, C(2)=2, C(3)=1, C(4)=1, C(5)=2 et C(6)=2. Pour six, les choix finaux donnent 1+C(2)=3 avec une pièce de quatre, 1+C(3)=2 avec une pièce de trois, ou 1+C(5)=3 avec une pièce de un.
Calculer de zéro vers la somme cible garantit que les résultats nécessaires existent déjà. La table rend visibles les dépendances et évite les appels répétés. Le calcul ne choisit pas seulement une pièce localement intéressante ; il compare des solutions complètes de sous-problèmes.
Mémoriser ou remplir un tableau
Une version récursive mémorisée conserve le résultat de chaque état à son premier calcul. Une version ascendante remplit directement le tableau dans l’ordre nécessaire. Les deux utilisent la même décomposition, mais organisent différemment le contrôle de l’exécution.
def minimum_pieces(somme, pieces):
cout = [0] + [float("inf")] * somme
for s in range(1, somme + 1):
for p in pieces:
if p <= s:
cout[s] = min(cout[s], 1 + cout[s - p])
return cout[somme]Les préconditions sont une somme entière naturelle et des valeurs de pièces entières strictement positives. Sans positivité, les dépendances ne se dirigent plus nécessairement vers des sommes plus petites.
Réutiliser l’idée et compter les ressources
Pour une cible S et k valeurs de pièces, cette table examine au plus S×k possibilités et conserve S+1 coûts. La reconstruction demande aussi de mémoriser ou retrouver les choix optimaux. Une stratégie gloutonne peut être plus légère, mais ne garantit pas ici l’optimalité.
Un autre exemple est Fibonacci : F(n)=F(n-1)+F(n-2). La récursion naïve recalcule souvent les mêmes valeurs ; une table les réutilise. Si l’on veut seulement le dernier terme, deux valeurs précédentes suffisent et réduisent la mémoire. La bonne optimisation dépend de ce que l’on doit renvoyer : un coût seul, un résultat final ou une solution complète.
Exemple suivi : remplir puis reconstruire
Avec les pièces 4,3,1, calculons jusqu’à 8. Les coûts pour 0 à 8 sont 0,1,2,1,1,2,2,2,2. Pour 7, une dernière pièce 4 laisse 3, dont le coût vaut 1 : deux pièces suffisent. Une dernière pièce 3 laisse 4 et donne aussi deux. Pour 8, une dernière pièce 4 laisse 4 et donne encore deux pièces. Le minimum peut donc être obtenu par plusieurs choix, mais sa valeur est unique.
Pour reconstruire, stockons la pièce retenue lors d’une amélioration. Depuis 7, le choix 4 conduit au reste 3, puis le choix 3 conduit à zéro : [4,3] forme bien la somme et contient C(7)=2 pièces. La somme restante diminue strictement puisque les pièces sont positives. Conserver seulement le coût final ne donne pas immédiatement la composition ; il faut également les choix ou refaire une recherche parmi les transitions optimales.
Si la table choix contient pour chaque somme accessible une dernière pièce optimale, la reconstruction suivante accepte zéro et renvoie None pour une cible positive inaccessible. Elle suppose que le remplissage respecte les préconditions du cours.
def reconstruire(choix, somme):
if somme > 0 and choix[somme] is None:
return None
rendu = []
while somme > 0:
piece = choix[somme]
rendu.append(piece)
somme -= piece
return renduExemple suivi : un glouton bloqué face à une solution existante
Avec les pièces 6 et 4, la table contient C(0)=0, C(4)=1, C(6)=1, C(8)=2, tandis que 1,2,3,5 et 7 sont inaccessibles. Pour 8, essayer une dernière pièce 6 laisse 2 inaccessible ; essayer 4 laisse 4 accessible en une pièce. La solution optimale est donc 4+4. Le glouton prend 6, laisse 2 et échoue, bien qu’une solution existe.
Le marqueur infini doit rester défavorable : 1+infini vaut encore infini dans ce modèle. Initialiser tous les coûts à zéro inventerait des solutions gratuites aux sommes impossibles. Les sommes impaires sont ici impossibles puisque chaque pièce est paire, mais toutes les sommes paires ne sont pas possibles : 2 est un contre-exemple. Utilisez la structure des données pour établir certaines impossibilités, puis la table pour vérifier précisément chaque cible.
À vous de faire varier les choses
Construisez le meilleur rendu de monnaie
Changez la somme et le système de pièces. La table affiche le minimum et une dernière pièce optimale ; le cas sans pièce de un révèle des sommes impossibles.
Lire le résultat de l’expérience initiale
Solution optimale : 3 + 3.
Le glouton utilise 3 pièce(s) : 4 + 1 + 1.
| Somme | Minimum de pièces | Dernière pièce choisie |
|---|---|---|
| 0 | 0 | Aucune |
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 1 | 3 |
| 4 | 1 | 4 |
| 5 | 2 | 4 |
| 6 | 2 | 3 |
L’optimalité se construit en comparant des sous-solutions ; les cas impossibles doivent rester identifiables.
De la compréhension à l’autonomie
À vous de résoudre
Cherchez d’abord par vous-même. Vérifiez les résultats demandés, utilisez les indices si nécessaire, puis comparez votre méthode à la correction.
Comparer au glouton
Avec les pièces 4,3,1 et une cible six, comparez le choix glouton et une solution optimale.
Indice 1
Le glouton prend quatre en premier.
Indice 2
Deux pièces de trois atteignent également six.
Comprendre la correction
Le glouton produit 4+1+1, soit trois pièces. L’optimal est 3+3, soit deux pièces. Une seule pièce ne peut pas former six, donc deux est bien minimal. Ce contre-exemple montre que le choix local le plus grand peut être sous-optimal.
Calculer une case
Pour les pièces 4,3,1, on connaît C(1)=1, C(2)=2 et C(4)=1. Calculez C(5).
Indice 1
Essayez une dernière pièce de quatre, trois puis un.
Indice 2
Comparez 1+C(1), 1+C(2) et 1+C(4).
Comprendre la correction
Les trois possibilités valent deux, trois et deux. Donc C(5)=2, obtenu par 4+1 ou 1+4, qui décrivent le même ensemble de valeurs dans un ordre différent. Il n’est pas nécessaire de distinguer ces ordres si l’objectif compte seulement les pièces.
Traiter une somme impossible
Avec seulement des pièces de 4 et 6, peut-on former trois ? Quelle valeur conceptuelle faut-il conserver dans la table ?
Indice 1
Aucune pièce ne tient dans cette somme.
Indice 2
Zéro signifierait une solution sans pièce.
Comprendre la correction
Trois est inaccessible. Il faut conserver un marqueur comme l’infini ou une absence explicite de résultat. Zéro serait incorrect : il désigne la solution de la somme nulle. Les états impossibles ne doivent pas devenir artificiellement avantageux dans un minimum.
Choisir la mémoire utile
Pour Fibonacci, on veut seulement F(n), pas tous les termes. Pourquoi deux valeurs précédentes peuvent-elles suffire, contrairement à une table complète ?
Indice 1
La prochaine valeur dépend de deux termes voisins.
Indice 2
Les termes plus anciens ne seront plus utilisés pour la suite.
Comprendre la correction
Après avoir calculé F(k), on peut conserver seulement F(k-1) et F(k) pour obtenir F(k+1). Les valeurs antérieures ne sont plus nécessaires à cette tâche. Cette réduction ne s’applique pas automatiquement à d’autres récurrences ni à un besoin d’afficher tout l’historique.
Problème : remplir une table avec des trous
Avec les pièces 6 et 4 en quantité illimitée, donnez les coûts minimaux de 0 à 10, en notant « impossible » lorsque nécessaire. Comparez le glouton et l’optimum pour 8 et pour 10. Pourquoi une somme paire n’est-elle pas une garantie suffisante de réalisabilité ?
Indice 1
Une somme se construit seulement depuis une case déjà accessible.
Indice 2
Pour 8, prendre 6 laisse un reste impossible.
Comprendre la correction
Les coûts sont 0, impossible, impossible, impossible, 1, impossible, 1, impossible, 2, impossible, 2. Pour 8, l’optimum 4+4 utilise deux pièces alors que le glouton échoue après 6. Pour 10, 6+4 réussit avec deux pièces pour les deux méthodes. La parité est une condition nécessaire mais 2 reste impossible : elle n’est pas suffisante.
Problème : retrouver une solution à partir des choix
Pour les pièces 4,3,1, les choix mémorisés sont choix[10]=4, choix[6]=3 et choix[3]=3. Reconstituez le rendu de 10, vérifiez somme et longueur, puis expliquez la terminaison de cette remontée. Que se passerait-il si une pièce de valeur zéro était autorisée comme choix ?
Indice 1
Soustrayez la pièce de la somme restante.
Indice 2
Le reste doit décroître strictement jusqu’à zéro.
Comprendre la correction
La remontée suit 10→6→3→0 et produit [4,3,3]. Sa somme vaut 10 et elle contient trois pièces. La positivité de chaque choix assure la diminution du reste. Avec un choix zéro, le reste resterait identique et la reconstruction pourrait boucler : la précondition sur les pièces protège aussi cette étape, pas seulement le remplissage.
Problème : distinguer ressources et résultat
Pour une cible S=30 et trois valeurs de pièces, combien de coûts stocke la table du cours ? Combien de tests de pièces sont exécutés par les deux boucles ? Pour Fibonacci, expliquez pourquoi ne conserver que deux termes peut convenir au dernier résultat mais pas à l’affichage de toute la table.
Indice 1
La case zéro est incluse dans la mémoire.
Indice 2
La boucle des pièces est exécutée pour chaque somme de 1 à S.
Comprendre la correction
La table contient 31 coûts. Les boucles exécutent 30×3=90 tests de la condition p≤s, même si toutes les transitions ne sont pas admissibles. Pour Fibonacci, les deux termes récents suffisent à calculer le suivant ; si l’on doit afficher ensuite tous les termes, il faut les conserver ou les recalculer. Le résultat demandé détermine donc la mémoire pertinente.
Les erreurs qui méritent un détour
- Remplir les cases avant leurs dépendances.
- Chaque état doit utiliser des sous-résultats déjà fiables.
- Confondre minimum de coût et reconstruction de solution.
- Un coût ne donne pas seul la liste des choix qui l’atteint.
La fiche à garder
L’essentiel à retenir
- La programmation dynamique réutilise des sous-problèmes communs.
- L’état, la base et la récurrence déterminent le tableau.
- Temps, mémoire et reconstruction dépendent du résultat demandé.
Cette notion au bac
Retrouvez ces idées dans un sujet complet, avec des indices, une correction expliquée et des ateliers.
- Bac 2026 · Amérique du Nord · Jour 1 : Immeubles : SQL et plus longue sous-séquence croissante
- Bac 2026 · Antilles-Guyane · Jour 1 : Plus longue sous-séquence commune : de l’exhaustif au dynamique
- Bac 2026 · Antilles-Guyane · Jour 2 : Scierie : valoriser le stock et optimiser les découpes
- Bac 2026 · Polynésie · Jour 1 : Fibonacci : mesurer le prix des calculs répétés
Le prochain pas
Retrouver le catalogue de Terminale
Ce chapitre s’appuie sur le programme officiel de Terminale (PDF, nouvel onglet). Les explications et exercices sont proposés pour l’apprentissage.
