// 1860 ms 偶尔提交会超时 classSolution { public: stringshortestSuperstring(vector<string>& A){ int n = A.size(); vector<vector<int>> cost(n, vector<int>(n)); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cost[i][j] = A[j].size(); if (j == i) continue; int len = min(A[i].size(), A[j].size()); for (int k = 1; k < len; ++k) { if (A[i].substr(A[i].size()-k) == A[j].substr(0, k)) cost[i][j] = A[j].size()-k; } } } vector<int> path, curPath; int maxCost = INT_MAX; dfs(path, curPath, maxCost, 0, 0, cost); string ans = A[path[0]]; for (int i = 1; i < path.size(); ++i) { int index = path[i]; int lastIndex = path[i-1]; int c = cost[lastIndex][index]; ans += A[index].substr(A[index].size()-c); } return ans; }
voiddfs(vector<int> &path, vector<int> &curPath, int &maxCost, int curCost, int used, vector<vector<int>> &cost){ int n = cost.size(); if (curCost >= maxCost) return; if (curPath.size() == n) { maxCost = curCost; path = curPath; return; } if (curPath.size() == 0) { for (int i = 0; i < n; ++i) { curPath.push_back(i); dfs(path, curPath, maxCost, cost[i][i], used|(1<<i), cost); curPath.pop_back(); } } else { int lastPoint = curPath.back(); for (int i = 0; i < n; ++i) { if (used&(1<<i)) continue; curPath.push_back(i); dfs(path, curPath, maxCost, curCost+cost[lastPoint][i], used|(1<<i), cost); curPath.pop_back(); } } } };
classSolution { public: stringshortestSuperstring(vector<string>& A){ int n = A.size(); vector<vector<int>> cost(n, vector<int>(n)); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cost[i][j] = A[j].size(); if (j == i) continue; int len = min(A[i].size(), A[j].size()); for (int k = 1; k < len; ++k) { if (A[i].substr(A[i].size()-k) == A[j].substr(0, k)) cost[i][j] = A[j].size()-k; } } } vector<vector<int>> dp(1<<n, vector<int>(n, INT_MAX/2)); vector<vector<int>> parent(1<<n, vector<int>(n)); for (int i = 0; i < n; ++i) { dp[1<<i][i] = A[i].size(); } for (int i = 0; i < (1<<n); ++i) { for (int j = 0; j < n; ++j) { if (((1<<j)&i) == 0) continue; for (int p = 0; p < n; ++p) { if (j == p || ((1<<p)&i) == 0) continue; int prev = i&(~(1<<j)); if (dp[prev][p] + cost[p][j] < dp[i][j]) { dp[i][j] = dp[prev][p] + cost[p][j]; parent[i][j] = p; } } } } int last = 0; int maxCost = INT_MAX; for (int i = 0; i < n; i++) { if (maxCost > dp[(1<<n)-1][i]) { last = i; maxCost = dp[(1<<n)-1][i]; } } string ans = A[last]; for (int i = 0, state = (1<<n)-1; i < n-1; ++i) { int j = parent[state][last]; int size = A[j].size() - (A[last].size() - cost[j][last]); ans = A[j].substr(0, size) + ans; state = state & ~(1<<last); last = j; }