每两个字符串连边,边的长度等价于这两个字符串的重和长度,问题:就是要求一条简单路径走过所有的点,并且长度最长。
设表示第
个点到集合
的最长路径,
表示这个集合内的点的
。
所以转移就是 ,
从小到大。
class Solution {
public:
bool equ(string a,string b){return a==b;}
string cal(string a,string b){
int n=a.size(),m=b.size();
int pos=0;
for (int len=min(n,m);len;len--){
if(equ(a.substr(n-len),b.substr(0,len))){
pos=len;break;
}
}
return a+b.substr(pos);
}
string shortestSuperstring(vector<string>& A) {
int dp[13][1<<12|1]={0};
int dis[13][13],path[13][1<<12|1];
int n=A.size();if(n==1)return A[0];
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
if(i==j)continue;
dis[i][j] =A[i].size()+A[j].size()-cal(A[i],A[j]).size();
}
}
for (int j=1;j<(1<<n);j++){
for(int i=0;i<n;i++){
if(j&(1<<i))continue;
for(int k=0;k<n;k++){
if((j&(1<<k))&&i!=k){
if(dp[i][j]<=dis[i][k]+dp[k][j^(1<<k)]){
dp[i][j]=dis[i][k]+dp[k][j^(1<<k)];
path[i][j]=k;
}
}
}
}
}
int p=0,S=(1<<n)-1;
for(int i=0;i<n;i++)if(dp[i][S^(1<<i)]>dp[p][S^(1<<p)])p=i;
vector<int>v;
while(S){
v.push_back(p);
S^=1<<p;
p=path[p][S];
}
string s=A[v[0]];
for(int i=1;i<n;i++)s=cal(s,A[v[i]]);
return s;
}
};
京公网安备 11010502036488号