C# DP
Intuition\nDP\n\n# Approach\ndp[mask][i] := min distance to visit nodes (represented as a binary state s) once and only once and the path ends with node i.\n\n#
# Intuition\nDP\n\n# Approach\ndp[mask][i] := min distance to visit nodes (represented as a binary state s) once and only once and the path ends with node i.\n\n# Complexity\n- Time complexity:\nO(n^2*2^n)\n\n- Space complexity:\nO(n*2^n)\n\n# Code\n```csharp []\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\npublic class Solution {\n    public string ShortestSuperstring(string[] words) {\n        int n = words.Length;\nint[,] graph = new int[n, n];\nfor (int i = 0; i < n; i++)\n{\n    for (int j = 0; j < n; j++)\n    {\n        graph[i, j] = words[j].Length;\n        \n        for (int k = 1; k <= Math.Min(words[i].Length, words[j].Length); k++)\n        {\n            if (words[j].Substring(0, k) == words[i].Substring(words[i].Length - k))\n            {\n                graph[i, j] = words[j].Length - k;\n            }\n        }\n    }\n}\n\n// path and last index get minlength\nint[,] dp = new int[1 << n, n];\nvar data = MemoryMarshal.CreateSpan(ref Unsafe.As<byte, int>(ref MemoryMarshal.GetArrayDataReference(dp)), dp.Length);\ndata.Fill(21 * 13);\n// path and last index with minLength get next last index\nint[,] paths = new int[1 << n, n];\nvar data2 = MemoryMarshal.CreateSpan(ref Unsafe.As<byte, int>(ref MemoryMarshal.GetArrayDataReference(paths)), paths.Length);\ndata2.Fill(-1);\nfor (int i = 0; i < n; i++)\n{\n    dp[1 << i, i] = words[i].Length;\n}\nfor (int mask = 0; mask < (1 << n); mask++)\n{\n    for (int i = 0; i < n; i++)\n    {\n        // mask not include i n\n        if ((mask & (1 << i)) == 0) continue;\n        int prev = mask ^ (1 << i);\n        for (int j = 0; j < n; j++)\n        {\n            // prev mask not include j\n            if ((prev & (1 << j)) == 0) continue;\n            if (dp[prev, j] + graph[j, i] < dp[mask, i])\n            {\n                dp[mask, i] = dp[prev, j] + graph[j, i];\n                paths[mask, i] = j;\n            }\n        }\n    }\n   \n    \n\n}\nint minLength = int.MaxValue;\nint currentIndex = -1;\nfor (int i = 0; (i < n); i++)\n{\n    if (dp[(1 << n) - 1, i] < minLength)\n    {\n        minLength = Math.Min(minLength, dp[(1 << n) - 1, i]);\n        currentIndex = i;\n    }\n\n}\nstring ans = "";\nint path = (1 << n) - 1;\nwhile (path > 0)\n{\n    int prev = paths[path,currentIndex];\n    if (prev >= 0)\n    {\n        ans = words[currentIndex].Substring(words[currentIndex].Length - graph[prev, currentIndex]) + ans;\n    }else\n    {\n        ans = words[currentIndex]+ ans;\n    }\n    path = path^(1<<currentIndex);\n    currentIndex= prev;\n\n}\nreturn ans;\n    }\n}\n```
['Dynamic Programming', 'Bit Manipulation', 'C#']