L'an dernier nous avons vu le problème du rendu de monnaie et nous l'avons résolue dans des cas particuliers en utilisant la méthode gloutonne. Malheureusement dans le cas général, la méthode ne marche pas. Par exemple si on ne possède que des pièces de 1 de 4 et de 5 et on veut avoir 8 la méthode gloutonne donne quatre pièces (5-1-1-1) alors que la solution optimale est 2 (4-4).
Pour n entier, soit Mn un ensemble de pièces réalisant une solution au problème du rendu de monnaie de n avec les pièces 1, 4 et 5 (par exemple), alors :
Si Mn possède une pièce de valeur 1 alors Mn\{1} est solution de Mn-1.
Si Mn possède une pièce de valeur 4 alors Mn\{4} est solution de Mn-4.
Si Mn possède une pièce de valeur 5 alors Mn\{5} est solution de Mn-5.
Nous sommes forcément dans un des cas suivants, donc on peut se ramener à chercher Mn-1, Mn-4 et Mn-5 puis à choisir l'ensemble le plus petit puis ajouter un pièce pour trouver Mn.
Cela ressemble assez à la méthode diviser pour régner (sauf que pour diviser pour reigner sépare le problème à des sous problèmes indépendants.) et on peut avoir conclure par une version récursive de la façon suivante :
Il y a un gros problème dans la version précédente, la récursivité multiplie les calculs.
Le principe de la programmation dynamique est de mémoriser les solutions précédentes pour éviter cette répétition.
Il existe deux méthodes pour programmer de façon dynamique.
Première méthode : memoïsation
La première méthode est simple à mettre en place, on part de la programmation récursive et on ajoute un dictionnaire qui enregistre les résultats déjà calculé, ensuite on regarde si la solution 'existe pas déjà.
Deuxième méthode : construction progressive
Une autre façon de programmer de manière dynamique est de partir du début et progressivement arriver à la solution, on va donc dans le sens inverse des précédents !