diff --git a/Programmation_Dynamique/Corrige_Exercices.md b/Programmation_Dynamique/Corrige_Exercices.md
deleted file mode 100644
index 8cc65ac..0000000
--- a/Programmation_Dynamique/Corrige_Exercices.md
+++ /dev/null
@@ -1,177 +0,0 @@
-# Corrigé — Exercices Programmation Dynamique
-
-## Exercice 1 — L'escalier
-
-**1.** Pour `n = 5` : escalier(5) = escalier(4) + escalier(3) = 5 + 3 = **8 façons**
-
-**2.** La suite `escalier(n)` suit la **suite de Fibonacci** (décalée d'un rang) : 1, 2, 3, 5, 8, 13...
-
-**3.** Relation de récurrence :
-```
-escalier(1) = 1
-escalier(2) = 2
-escalier(n) = escalier(n-1) + escalier(n-2) pour n > 2
-```
-
-**4.** Version mémoïsation :
-
-```python
-def escalier_memo(n):
- memo = {1: 1, 2: 2}
-
- def escalier(k):
- if k in memo:
- return memo[k]
- memo[k] = escalier(k - 1) + escalier(k - 2)
- return memo[k]
-
- return escalier(n)
-```
-
-**5.** Version bottom-up :
-
-```python
-def escalier_bottom_up(n):
- if n == 1:
- return 1
- tableau = [0] * (n + 1)
- tableau[1] = 1
- tableau[2] = 2
- for i in range(3, n + 1):
- tableau[i] = tableau[i - 1] + tableau[i - 2]
- return tableau[n]
-```
-
-**6.** Vérification :
-
-```python
-for i in range(1, 11):
- assert escalier_memo(i) == escalier_bottom_up(i), f"Erreur pour n={i}"
-print("Toutes les valeurs correspondent !")
-# Résultats : 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
-```
-
-## Exercice 2 — Rendu de monnaie revisité
-
-**1.** Avec les pièces [2, 5, 10] et somme = 6 : le glouton prend 5 (la plus grande pièce ≤ 6), il reste 1 à rendre, mais aucune pièce de [2, 5, 10] ne permet de rendre 1. **Le glouton échoue.**
-
-**2.** Oui. La programmation dynamique explore toutes les combinaisons et trouve : 2+2+2 = **3 pièces**. La somme 6 est bien rendable, le glouton était simplement mal parti en choisissant 5 en premier.
-
-**3.** `rendu_bottom_up` :
-
-```python
-def rendu_bottom_up(pieces, somme):
- tableau = [float('inf')] * (somme + 1)
- tableau[0] = 0
- for s in range(1, somme + 1):
- for piece in pieces:
- if piece <= s and tableau[s - piece] + 1 < tableau[s]:
- tableau[s] = tableau[s - piece] + 1
- return tableau[somme]
-
-# Tests
-print(rendu_bottom_up([2, 5, 10], 6)) # 3 (2+2+2)
-print(rendu_bottom_up([1, 3, 4], 6)) # 2 (3+3)
-print(rendu_bottom_up([1, 5, 6, 9], 11)) # 2 (5+6)
-```
-
-**4.** Version avec reconstruction :
-
-```python
-def rendu_avec_pieces(pieces, somme):
- tableau = [float('inf')] * (somme + 1)
- tableau[0] = 0
- derniere_piece = [-1] * (somme + 1) # mémorise quelle pièce a été utilisée
-
- for s in range(1, somme + 1):
- for piece in pieces:
- if piece <= s and tableau[s - piece] + 1 < tableau[s]:
- tableau[s] = tableau[s - piece] + 1
- derniere_piece[s] = piece
-
- # Reconstruction
- pieces_utilisees = []
- s = somme
- while s > 0:
- p = derniere_piece[s]
- pieces_utilisees.append(p)
- s -= p
-
- return tableau[somme], pieces_utilisees
-
-print(rendu_avec_pieces([1, 3, 4], 6))
-# (2, [3, 3])
-```
-
-## Exercice 3 — Sac à dos : à la main et en code
-
-**1.** Tableau `tableau[i][w]` :
-
-objets = [(1,2), (2,5), (3,8), (4,9)], capacité = 6
-
-| | w=0 | w=1 | w=2 | w=3 | w=4 | w=5 | w=6 |
-|---|-----|-----|-----|-----|-----|-----|-----|
-| i=0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| i=1 (A:1kg,2) | 0 | 2 | 2 | 2 | 2 | 2 | 2 |
-| i=2 (+B:2kg,5) | 0 | 2 | 5 | 7 | 7 | 7 | 7 |
-| i=3 (+C:3kg,8) | 0 | 2 | 5 | 8 | 10 | 13 | 15 |
-| i=4 (+D:4kg,9) | 0 | 2 | 5 | 8 | 10 | 13 | 15 |
-
-**2.** Valeur maximale : **15**
-
-**3.** Reconstruction depuis `tableau[4][6] = 15` :
-- `tableau[4][6] = tableau[3][6]` → D non pris, w reste 6
-- `tableau[3][6] = 15 ≠ tableau[2][6] = 7` → C pris (3kg), w = 6-3 = 3
-- `tableau[2][3] = 7 ≠ tableau[1][3] = 2` → B pris (2kg), w = 3-2 = 1
-- `tableau[1][1] = 2 ≠ tableau[0][1] = 0` → A pris (1kg), w = 0
-
-Solution : **A + B + C** = 2+5+8 = 15 ✓
-
-**4.** Vérification :
-
-```python
-objets = [(1, 2), (2, 5), (3, 8), (4, 9)]
-valeur, choix = sac_reconstruction(objets, 6)
-print(valeur, choix) # 15, [(3, 8), (2, 5), (1, 2)]
-```
-
-## Exercice 4 — Triangle de Pascal
-
-**1.** Relation de récurrence :
-```
-pascal(0, 0) = 1
-pascal(n, 0) = 1 ← bord gauche
-pascal(n, n) = 1 ← bord droit
-pascal(n, k) = pascal(n-1, k-1) + pascal(n-1, k) pour 0 < k < n
-```
-
-**2.** Implémentation bottom-up :
-
-```python
-def triangle_pascal(n):
- triangle = []
- for ligne in range(n):
- t = [1] * (ligne + 1) # initialise avec des 1
- for k in range(1, ligne): # cases intérieures
- t[k] = triangle[ligne-1][k-1] + triangle[ligne-1][k]
- triangle.append(t)
- return triangle
-```
-
-**3.** Vérification :
-
-```python
-resultat = triangle_pascal(5)
-assert resultat == [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
-print("Correct !")
-```
-
-**4.** Bonus : La somme des éléments de la ligne `n` est `2ⁿ`. Par exemple, ligne 4 : 1+4+6+4+1 = 16 = 2⁴. Lien avec Fibonacci : la somme des diagonales "montantes" du triangle de Pascal donne les nombres de Fibonacci.
-
----
-
-Auteur : Florian Mathieu
-
-Licence CC BY NC
-
-
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.
diff --git a/Programmation_Dynamique/Corrige_TP_Donjon.md b/Programmation_Dynamique/Corrige_TP_Donjon.md
deleted file mode 100644
index 523f400..0000000
--- a/Programmation_Dynamique/Corrige_TP_Donjon.md
+++ /dev/null
@@ -1,194 +0,0 @@
-# Corrigé — TP Le Donjon du Dragon
-
-## Partie 1 — Comprendre le problème
-
-**Question 1.** Chemins de `(0,0)` à `(2,3)` (grille 3×4) en allant uniquement droite/bas :
-Il faut faire exactement 3 pas vers la droite et 2 pas vers le bas, soit C(5,2) = **10 chemins**.
-
-**Question 2.** Le chemin optimal est `(0,0)→(1,0)→(1,1)→(2,1)→(2,2)→(2,3)` : 3+5+9+2+8-5 = **22** d'or.
-
-| Chemin | Or total |
-|--------|----------|
-| Tout droite puis tout bas | 3-1+4+1+6-5 = **8** |
-| Bas, droite×3, bas | 3+5+9-2+6-5 = **16** |
-| Bas×2, droite×3 | 3+5-3+2+8-5 = **10** |
-| Bas, droite, bas, droite×2 | 3+5+9+2+8-5 = **22** ← optimal |
-
-**Question 3.** Pour une grille `n×m`, le nombre de chemins est C(n+m-2, n-1) (combinaison : choisir quand descendre parmi tous les pas).
-
-## Partie 2 — Formulation récursive
-
-**Question 4.** Cas de base :
-- `donjon(i, 0)` : on ne peut aller que vers le bas → somme de la colonne 0 jusqu'à `i`
-- `donjon(0, j)` : on ne peut aller que vers la droite → somme de la ligne 0 jusqu'à `j`
-
-**Question 5.** Relation générale :
-```
-donjon(i, j) = grille[i][j] + max(donjon(i-1, j), donjon(i, j-1))
-```
-*(On arrive en `(i,j)` depuis le haut ou depuis la gauche, on choisit le meilleur.)*
-
-**Question 6.** Version naïve :
-
-```python
-def donjon_naif(grille, i, j):
- if i == 0 and j == 0:
- return grille[0][0]
- if i == 0:
- return grille[0][j] + donjon_naif(grille, 0, j - 1)
- if j == 0:
- return grille[i][0] + donjon_naif(grille, i - 1, 0)
- return grille[i][j] + max(donjon_naif(grille, i - 1, j),
- donjon_naif(grille, i, j - 1))
-
-grille = [
- [ 3, -1, 4, 1],
- [ 5, 9, -2, 6],
- [-3, 2, 8, -5]
-]
-n, m = len(grille), len(grille[0])
-print(donjon_naif(grille, n - 1, m - 1)) # 22
-```
-
-## Partie 3 — Version Top-Down (mémoïsation)
-
-**Question 7.** Oui, beaucoup de sous-problèmes sont recalculés. Par exemple, `donjon(1,1)` est appelé depuis `donjon(2,1)` et depuis `donjon(1,2)`.
-
-```python
-compteur = 0
-
-def donjon_naif_compte(grille, i, j):
- global compteur
- compteur += 1
- if i == 0 and j == 0:
- return grille[0][0]
- if i == 0:
- return grille[0][j] + donjon_naif_compte(grille, 0, j - 1)
- if j == 0:
- return grille[i][0] + donjon_naif_compte(grille, i - 1, 0)
- return grille[i][j] + max(donjon_naif_compte(grille, i - 1, j),
- donjon_naif_compte(grille, i, j - 1))
-
-donjon_naif_compte(grille, 2, 3)
-print(f"Nombre d'appels : {compteur}") # bien plus que les 12 cases de la grille
-```
-
-**Question 8.** Version mémoïsation :
-
-```python
-def donjon_memo(grille):
- n = len(grille)
- m = len(grille[0])
- memo = {}
-
- def donjon(i, j):
- if (i, j) in memo:
- return memo[(i, j)]
- if i == 0 and j == 0:
- resultat = grille[0][0]
- elif i == 0:
- resultat = grille[0][j] + donjon(0, j - 1)
- elif j == 0:
- resultat = grille[i][0] + donjon(i - 1, 0)
- else:
- resultat = grille[i][j] + max(donjon(i - 1, j), donjon(i, j - 1))
- memo[(i, j)] = resultat
- return resultat
-
- return donjon(n - 1, m - 1)
-
-print(donjon_memo(grille)) # 22
-```
-
-**Question 9.** Les deux versions donnent 22 ✓
-
-## Partie 4 — Version Bottom-Up (tableau)
-
-**Question 10.** Tableau `t[i][j]` = or max depuis `(0,0)` jusqu'à `(i,j)` :
-
-```
-grille : tableau :
-[ 3, -1, 4, 1] [ 3, 2, 6, 7]
-[ 5, 9, -2, 6] [ 8, 17, 15, 21]
-[-3, 2, 8, -5] [ 5, 19, 27, 22]
-```
-
-**Question 11.** Implémentation :
-
-```python
-def donjon_bottom_up(grille):
- n = len(grille)
- m = len(grille[0])
- tableau = [[0] * m for _ in range(n)]
-
- tableau[0][0] = grille[0][0]
-
- for j in range(1, m): # première ligne
- tableau[0][j] = tableau[0][j - 1] + grille[0][j]
-
- for i in range(1, n): # première colonne
- tableau[i][0] = tableau[i - 1][0] + grille[i][0]
-
- for i in range(1, n): # reste du tableau
- for j in range(1, m):
- tableau[i][j] = grille[i][j] + max(tableau[i - 1][j],
- tableau[i][j - 1])
-
- return tableau[n - 1][m - 1]
-
-print(donjon_bottom_up(grille)) # 22
-```
-
-**Question 12.** Les trois versions donnent 22 ✓
-
-## Partie 5 — Bonus : retrouver le chemin optimal
-
-**Question 13.** Reconstruction du chemin :
-
-```python
-def donjon_chemin(grille):
- n = len(grille)
- m = len(grille[0])
- tableau = [[0] * m for _ in range(n)]
-
- tableau[0][0] = grille[0][0]
- for j in range(1, m):
- tableau[0][j] = tableau[0][j - 1] + grille[0][j]
- for i in range(1, n):
- tableau[i][0] = tableau[i - 1][0] + grille[i][0]
- for i in range(1, n):
- for j in range(1, m):
- tableau[i][j] = grille[i][j] + max(tableau[i - 1][j],
- tableau[i][j - 1])
-
- # Reconstruction : on remonte depuis (n-1, m-1)
- chemin = []
- i, j = n - 1, m - 1
- while i > 0 or j > 0:
- chemin.append((i, j))
- if i == 0:
- j -= 1
- elif j == 0:
- i -= 1
- elif tableau[i - 1][j] > tableau[i][j - 1]:
- i -= 1
- else:
- j -= 1
- chemin.append((0, 0))
- chemin.reverse()
-
- return tableau[n - 1][m - 1], chemin
-
-
-valeur, chemin = donjon_chemin(grille)
-print(f"Or maximal : {valeur}") # 22
-print(f"Chemin optimal : {chemin}") # [(0,0), (1,0), (1,1), (2,1), (2,2), (2,3)]
-```
-
----
-
-Auteur : Florian Mathieu
-
-Licence CC BY NC
-
-
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.
diff --git a/Programmation_Dynamique/Corrige_TP_Vaccin.md b/Programmation_Dynamique/Corrige_TP_Vaccin.md
deleted file mode 100644
index e1e7b4f..0000000
--- a/Programmation_Dynamique/Corrige_TP_Vaccin.md
+++ /dev/null
@@ -1,190 +0,0 @@
-# Corrigé — TP L'Algorithme du Vaccin
-
-## Partie 1 — Comprendre le problème
-
-**Question 1.** Algorithme glouton (tri par ratio efficacité/temps décroissant) :
-
-Ratios : Gamma (15,0), Delta (14,3), Epsilon (14,2), Bêta (14,0), Alpha (13,3)
-
-- Prendre Gamma : 2 h utilisées, efficacité 30, reste 8 h
-- Prendre Delta : 2+7=9 h utilisées, efficacité 130, reste 1 h
-- Plus aucun anticorps ne tient en 1 h → arrêt
-
-**Résultat glouton : 130** (Gamma + Delta)
-
-**Question 2.** Oui : Alpha + Bêta + Gamma = 3+5+2 = 10 h, efficacité 40+70+30 = **140**. Le glouton a raté la solution optimale.
-
-**Question 3.** Pour 5 anticorps : 2⁵ = 32 combinaisons. Pour 30 anticorps : 2³⁰ ≈ 1 milliard. L'approche exhaustive devient impraticable très rapidement.
-
----
-
-## Partie 2 — Formulation récursive
-
-**Question 4.** Cas de base :
-- `vaccin(0, t) = 0` (aucun anticorps disponible)
-- `vaccin(i, 0) = 0` (temps épuisé)
-
-**Question 5.** Relation de récurrence :
-
-```
-vaccin(i, t) = vaccin(i-1, t) si duree_i > t
-vaccin(i, t) = max(vaccin(i-1, t), sinon
- eff_i + vaccin(i-1, t - duree_i))
-```
-
-**Question 6.** Version naïve :
-
-```python
-def vaccin_naif(anticorps, i, t):
- if i == 0 or t == 0:
- return 0
- duree, eff = anticorps[i - 1]
- if duree > t:
- return vaccin_naif(anticorps, i - 1, t)
- else:
- sans = vaccin_naif(anticorps, i - 1, t)
- avec = eff + vaccin_naif(anticorps, i - 1, t - duree)
- return max(sans, avec)
-
-anticorps = [(3, 40), (5, 70), (2, 30), (7, 100), (6, 85)]
-n = len(anticorps)
-print(vaccin_naif(anticorps, n, 10)) # 140
-```
-
----
-
-## Partie 3 — Version Top-Down (mémoïsation)
-
-**Question 7.** Oui. Par exemple, `vaccin(2, 5)` (2 premiers anticorps, 5 h restantes) peut être appelé en ne prenant pas Alpha, mais aussi après avoir pris Alpha (si on avait commencé avec 8 h). Sans mémoïsation, ce sous-problème est recalculé à chaque fois.
-
-**Question 8.** Version mémoïsation :
-
-```python
-def vaccin_memo(anticorps, temps_total):
- memo = {}
-
- def vaccin(i, t):
- if i == 0 or t == 0:
- return 0
- if (i, t) in memo:
- return memo[(i, t)]
- duree, eff = anticorps[i - 1]
- if duree > t:
- resultat = vaccin(i - 1, t)
- else:
- sans = vaccin(i - 1, t)
- avec = eff + vaccin(i - 1, t - duree)
- resultat = max(sans, avec)
- memo[(i, t)] = resultat
- return resultat
-
- return vaccin(len(anticorps), temps_total)
-
-print(vaccin_memo(anticorps, 10)) # 140
-```
-
-**Question 9.** Les deux versions donnent 140 ✓
-
----
-
-## Partie 4 — Version Bottom-Up (tableau)
-
-**Question 10.** Tableau pour Alpha (3h,40), Bêta (5h,70), Gamma (2h,30), T=6 :
-
-| | t=0 | t=1 | t=2 | t=3 | t=4 | t=5 | t=6 |
-|---|---|---|---|---|---|---|---|
-| i=0 (aucun) | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-| i=1 (Alpha 3h, 40) | 0 | 0 | 0 | 40 | 40 | 40 | 40 |
-| i=2 (+Bêta 5h, 70) | 0 | 0 | 0 | 40 | 40 | 70 | 70 |
-| i=3 (+Gamma 2h, 30) | 0 | 0 | 30 | 40 | 40 | 70 | 70 |
-
-Avec 6 h, le meilleur est Bêta seul (70), ou Gamma+Alpha ne tient pas car 2+3=5 h → efficacité 70 aussi.
-
-**Question 11.** Implémentation :
-
-```python
-def vaccin_bottom_up(anticorps, temps_total):
- n = len(anticorps)
- tableau = [[0] * (temps_total + 1) for _ in range(n + 1)]
-
- for i in range(1, n + 1):
- duree, eff = anticorps[i - 1]
- for t in range(temps_total + 1):
- if duree > t:
- tableau[i][t] = tableau[i - 1][t]
- else:
- tableau[i][t] = max(
- tableau[i - 1][t],
- eff + tableau[i - 1][t - duree]
- )
-
- return tableau[n][temps_total]
-
-print(vaccin_bottom_up(anticorps, 10)) # 140
-```
-
-**Question 12.** Les trois versions donnent 140 ✓
-
----
-
-## Partie 5 — Reconstruction de la solution
-
-**Question 13.** Reconstruction :
-
-```python
-def vaccin_reconstruction(anticorps, temps_total):
- n = len(anticorps)
- tableau = [[0] * (temps_total + 1) for _ in range(n + 1)]
-
- for i in range(1, n + 1):
- duree, eff = anticorps[i - 1]
- for t in range(temps_total + 1):
- if duree > t:
- tableau[i][t] = tableau[i - 1][t]
- else:
- tableau[i][t] = max(
- tableau[i - 1][t],
- eff + tableau[i - 1][t - duree]
- )
-
- # Reconstruction : on remonte le tableau
- choisis = []
- t = temps_total
- for i in range(n, 0, -1):
- if tableau[i][t] != tableau[i - 1][t]:
- choisis.append(anticorps[i - 1])
- t -= anticorps[i - 1][0]
-
- return tableau[n][temps_total], choisis
-
-
-efficacite, choix = vaccin_reconstruction(anticorps, 10)
-print(f"Efficacité maximale : {efficacite}") # 140
-print(f"Anticorps choisis : {choix}") # [(3,40), (5,70), (2,30)] → Alpha + Bêta + Gamma
-```
-
-**Question 14.** Vérification :
-- Alpha (3h) + Bêta (5h) + Gamma (2h) = **10 h** ≤ 10 h ✓
-- 40 + 70 + 30 = **140** ✓
-
-**Question 15.** Complexité :
-- **Temps : O(n × T)** — on remplit un tableau de n+1 lignes et T+1 colonnes
-- **Espace : O(n × T)** — pour stocker le tableau
-
-Avec n = nombre d'anticorps et T = temps total disponible.
-
----
-
-## Partie 6 — Bonus : contraintes supplémentaires
-
-**Question 16.** Pour gérer l'incompatibilité Alpha/Gamma, on peut ajouter une dimension à l'état : au lieu de `vaccin(i, t)`, on utilise `vaccin(i, t, alpha_pris)` où `alpha_pris` vaut 1 si Alpha a déjà été sélectionné, 0 sinon. Si `alpha_pris == 1` et que l'anticorps courant est Gamma (ou vice-versa), on interdit sa sélection.
-
-Cette approche généralise naturellement : chaque contrainte d'incompatibilité entre deux objets peut être encodée comme une variable booléenne supplémentaire dans l'état. La complexité devient O(n × T × 2^k) où k est le nombre de contraintes d'incompatibilité.
-
----
-
-Auteur : Florian Mathieu
-
-Licence CC BY NC
-
-
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.