1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| class { private: inline int calcOverlap(const string& s1, const string& s2) { int start = s1.length() - s2.length(); start = max(0, start); for (int i = start; i < s1.length(); i++) { int len = s1.length() - i; if (s1.substr(i, len) == s2.substr(0, len)) return len; } return 0; } inline bool contains(int cnt, int i) { return (cnt & (1 << i)) != 0; }大专栏 Leetcode 943. Find the Shortest Superstring(DP)> public: string shortestSuperstring(vector<string>& A) { int n = A.size(); if (n == 1) return A[0]; int overlap[n][n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) overlap[i][j] = calcOverlap(A[i], A[j]); const int MAX_CNT = (1 << n); int f[MAX_CNT][n], parent[MAX_CNT][n]; for (int i = 0; i < n; i++) { f[1 << i][i] = 0; parent[1 << i][i] = -1; } int ans = -1; int p = -1; for (int cnt = 2; cnt <= n; cnt++) { for (int i = 0; i < MAX_CNT; i++) { if (__builtin_popcount(i) != cnt) continue; for (int j = 0; j < n; j++) { if (!contains(i, j)) continue; f[i][j] = -1; int nmask = i ^ (1 << j); for (int k = 0; k < n; k++) { if (!contains(nmask, k)) continue; if (f[nmask][k] + overlap[k][j] > f[i][j]) { f[i][j] = f[nmask][k] + overlap[k][j]; parent[i][j] = k; } } if (cnt == n && f[i][j] > ans) { ans = f[i][j]; p = j; } } } } string str; int nmask = MAX_CNT - 1; while (true) { int par = parent[nmask][p]; if (par == -1) { str = A[p] + str; break; } str = A[p].substr(overlap[par][p], A[p].length() - overlap[par][p]) + str; nmask ^= (1 << p); p = par; } return str; } };
|