diff --git a/cs/minimum-cost-to-convert-string-i.cs b/cs/minimum-cost-to-convert-string-i.cs new file mode 100644 index 0000000..d8de4ed --- /dev/null +++ b/cs/minimum-cost-to-convert-string-i.cs @@ -0,0 +1,56 @@ +public class Solution { + private readonly int UNREACHABLE = 1_000_000_007; + private readonly int LETTERS = 26; + + private void FloydWarshall(int n, int[,] distances) { + for (int k = 0; k < n; ++k) { + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + distances[i, j] = Math.Min( + distances[i, j], + distances[i, k] + distances[k, j] + ); + } + } + } + } + + private int[,] ConstructGraph(char[] original, char[] changed, int[] costs) { + var distances = new int[LETTERS, LETTERS]; + + // Everything's unreachable + for (var i = LETTERS * LETTERS - 1; i >= 0; --i) { + distances[i / LETTERS, i % LETTERS] = UNREACHABLE; + } + + // Go through the possible changes + for (var i = 0; i < original.length; ++i) { + var (u, v, cost) = (original[i] - 'a', changed[i] - 'a', costs[i]); + distances[u, v] = Math.Min(distances[u, v], cost); + } + + // Handle self-loops + for (var i = 0; i < LETTERS; ++i) { + distances[i, i] = 0; + } + + return distances; + } + + public long MinimumCost(string source, string target, char[] original, char[] changed, int[] cost) { + var graph = ConstructGraph(original, changed, cost); + FloydWarshall(LETTERS, graph); + + var minCost = 0; + for (int i = 0; i < source.Length; ++i) { + var operationCost = graph[source[i] - 'a', target[i] - 'a']; + if (operationCost == UNREACHABLE) { + return -1; + } + + minCost += operationCost; + } + + return minCost; + } +}