枚举加深度搜索,虽然特别慢,但是快速解决问题还是不错的选择
#include<iostream>
#include<string.h>
#define MAXNUM 10
#define MAXSTR 21
using namespace std;
int t;
int n;
int minvalue;
int suffix[MAXNUM][MAXNUM];
typedef struct _segment{
char seg[MAXSTR];
int len;
bool visited;
}segment;
segment s[MAXNUM];
void input(){
int i;
cin >> n;
for(i=0;i<n;i++){
cin >> s[i].seg;
s[i].len = strlen(s[i].seg);
s[i].visited = false;
}
}
void init(){
int i,j,len,k,l,count;
bool flag;
minvalue = 999999;
memset(suffix,0,sizeof(int)*MAXNUM*MAXNUM);
for(i=0;i<n;i++)
for(j=0;j<n;j++){
if(i==j) continue;
len = s[i].len>s[j].len?s[j].len:s[i].len;
for(k=len;k>=0;k--){
flag = true;
for(l=k;l>0;l--){
if(s[i].seg[s[i].len-l] != s[j].seg[k-l]){
flag = false;
}
}
if(flag){
suffix[i][j] = s[j].len - k;
break;
}
}
}
}
void search(int level,int total,int seg){
int i;
if(total > minvalue) return;
if(level == n-1){
minvalue = total;
return;
}
for(i=0;i<n;i++){
if(s[i].visited) continue;
s[i].visited = true;
search(level+1,total+suffix[seg][i],i);
s[i].visited = false;
}
}
void solve(){
int i;
cin >> t;
while(t-->0){
input();
init();
for(i=0;i<n;i++){
s[i].visited = true;
search(0,s[i].len,i);
s[i].visited = false;
}
cout<<minvalue<<endl;
}
}
int main(){
solve();
}