diff --git a/README.md b/README.md
index 5c6fcfb..3829e76 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,7 @@
# WillsonAlgorithm
Wilson's algorithm can be used to solve the Traveling Salesman Problem (TSP). TSP is a well-known problem in combinatorial optimization where the goal is to find the shortest travel route that visits each city once and returns to the starting point.
-This example uses a coarse-grained approach to solving the Traveling Salesman Problem (TSP), which means it examines all possible permutations of routes to find the shortest one. Note that this approach is only practical for a smaller number of cities due to the exponential growth of combinations.
+
+This example uses a coarse-grained approach to solving the TSP, which means it examines all possible permutations of routes to find the shortest one. **The number of possibilities grows factorially** with the number of cities, so the algorithm quickly becomes infeasible as the problem size increases. It is only practical for small sets of cities.
+
+A dynamic-programming based alternative is provided in `DynamicProgrammingSalesman`. While it still has exponential complexity, it is significantly faster than brute force and demonstrates another way to approach the problem.
diff --git a/WillsonAlgorithm/DynamicProgrammingSalesman.cs b/WillsonAlgorithm/DynamicProgrammingSalesman.cs
new file mode 100644
index 0000000..d0fe1a1
--- /dev/null
+++ b/WillsonAlgorithm/DynamicProgrammingSalesman.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+
+namespace WillsonAlgorithm
+{
+ ///
+ /// Solves the Traveling Salesman Problem using a dynamic programming
+ /// approach (Held-Karp algorithm).
+ ///
+ public class DynamicProgrammingSalesman
+ {
+ private readonly int[,] _distanceMatrix;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Matrix with pairwise distances.
+ public DynamicProgrammingSalesman(int[,] distanceMatrix)
+ {
+ _distanceMatrix = distanceMatrix;
+ }
+
+ ///
+ /// Computes the optimal path and its total distance using dynamic programming.
+ ///
+ /// Tuple containing the best path and its distance.
+ public (List Path, int Distance) Solve()
+ {
+ int n = _distanceMatrix.GetLength(0);
+ var dp = new Dictionary<(int subset, int last), int>();
+ var parent = new Dictionary<(int subset, int last), int>();
+
+ // Initialize with paths that start at 0 and visit one city
+ for (int city = 1; city < n; city++)
+ {
+ int subset = 1 << city;
+ dp[(subset, city)] = _distanceMatrix[0, city];
+ parent[(subset, city)] = 0;
+ }
+
+ int allVisitedMask = (1 << n) - 2; // Exclude start city (0)
+ for (int subsetMask = 1; subsetMask <= allVisitedMask; subsetMask++)
+ {
+ // Skip subsets with only one bit set
+ if ((subsetMask & (subsetMask - 1)) == 0) continue;
+
+ for (int last = 1; last < n; last++)
+ {
+ if ((subsetMask & (1 << last)) == 0) continue;
+
+ int subsetWithoutLast = subsetMask ^ (1 << last);
+ int best = int.MaxValue;
+ int bestPrev = -1;
+
+ for (int prev = 1; prev < n; prev++)
+ {
+ if ((subsetWithoutLast & (1 << prev)) == 0) continue;
+ if (!dp.TryGetValue((subsetWithoutLast, prev), out int prevCost))
+ continue;
+
+ int cost = prevCost + _distanceMatrix[prev, last];
+ if (cost < best)
+ {
+ best = cost;
+ bestPrev = prev;
+ }
+ }
+
+ if (bestPrev != -1)
+ {
+ dp[(subsetMask, last)] = best;
+ parent[(subsetMask, last)] = bestPrev;
+ }
+ }
+ }
+
+ int bestDistance = int.MaxValue;
+ int bestLastCity = -1;
+ foreach (var kvp in dp)
+ {
+ var (subset, last) = kvp.Key;
+ if (subset != allVisitedMask) continue;
+ int cost = kvp.Value + _distanceMatrix[last, 0];
+ if (cost < bestDistance)
+ {
+ bestDistance = cost;
+ bestLastCity = last;
+ }
+ }
+
+ var path = new List { 0 };
+ int mask = allVisitedMask;
+ int cityCursor = bestLastCity;
+ var stack = new Stack();
+ while (cityCursor != 0 && cityCursor != -1)
+ {
+ stack.Push(cityCursor);
+ int prev = parent[(mask, cityCursor)];
+ mask ^= 1 << cityCursor;
+ cityCursor = prev;
+ }
+ while (stack.Count > 0)
+ {
+ path.Add(stack.Pop());
+ }
+ path.Add(0); // return to start
+
+ return (path, bestDistance);
+ }
+ }
+}
diff --git a/WillsonAlgorithm/TravelingSalesman.cs b/WillsonAlgorithm/TravelingSalesman.cs
index c31dea6..bf1d53b 100644
--- a/WillsonAlgorithm/TravelingSalesman.cs
+++ b/WillsonAlgorithm/TravelingSalesman.cs
@@ -1,5 +1,10 @@
namespace WillsonAlgorithm
{
+ ///
+ /// Brute-force solver for the Traveling Salesman Problem.
+ /// Examines every possible path and therefore has factorial complexity.
+ /// Suitable only for very small numbers of cities.
+ ///
public class TravelingSalesman
{
private readonly int[,] _distanceMatrix;