Zuosige always has bad luck. Recently, he is in hospital because of pneumonia. While he is taking his injection, he feels extremely bored. However, clever Zuosige comes up with a new game.
Zuosige writes some of his favorite strings on paper. And he wants to find out a string which has all these favorite strings as its substrings. However, as a sick man, he cannot remember a very long string, so he wants you to help him find out the shortest
one.
The first line contains one integer T, indicating the number of test cases.
In one test case, there are several lines.
In the first line, there are two integers n (1<=n<=12), indicating the number of strings he writes.
In the following n lines, each line has a string whose length is no more than 50. The strings only consists of uppercase letters.
For each test case, output an integer indicating the length of the shortest string containing all these strings.
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
using namespace std;
#define ls 2*i
#define rs 2*i+1
#define up(i,x,y) for(i=x;i<=y;i++)
#define down(i,x,y) for(i=x;i>=y;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define w(a) while(a)
#define LL long long
const double pi = acos(-1.0);
#define N 1000005
#define mod 19999997
#define INF 0x3f3f3f3f
#define exp 1e-8
int t,n;
char s[15][55],s1[15][55];
int dp[1<<13][55],len[15],cnt,flag;
int hsh[15][15];//hsh[i][j]表示j串接在i串后面,除掉合并的部分,实际上j串只加上去了hsh[i][j]的长度
int main()
{
int i,j,k,x,y;
cin>>t;
w(t--)
{
cin>>n;
up(i,0,n-1)
{
scanf("%s",s[i]);
}
cnt = 0;
up(i,0,n-1)
{
flag = 0;
up(j,0,n-1)
{
if(strstr(s[j],s[i]) && strcmp(s[i],s[j])) flag = 1;
}
if(!flag)
strcpy(s1[cnt++],s[i]);
}
n = 0;
up(i,0,cnt-1)
{
flag = 0;
up(j,0,i-1)
{
if(!strcmp(s1[i],s1[j])) flag = 1;
}
if(!flag)
strcpy(s[n++],s1[i]);
}
up(i,0,n-1)
{
len[i]=strlen(s[i]);
}
mem(hsh,0);
up(i,0,n-1)
{
up(j,0,n-1)
{
hsh[i][j] = len[j];
int pos = -1;
down(k,len[i]-1,1)
{
flag = 1;
up(x,k,len[i]-1)
{
if(s[i][x]!=s[j][x-k]) flag = 0;
}
if(flag) pos = k;
}
if(pos!=-1) hsh[i][j] = len[j]-len[i]+pos;
}
}
mem(dp,INF);
int size = (1<<n)-1,pre=0,now;
up(i,1,size)
{
up(j,0,n-1)
{
if(i&(1<<j))
{
pre = (i^(1<<j));
if(pre==0) dp[i][j] = len[j];
up(k,0,n-1)
{
if(j!=k && (i&(1<<k))==0)
{
now=(i|(1<<k));
dp[now][k]=min(dp[now][k],dp[i][j]+hsh[j][k]);
}
}
}
}
}
int minn = INF;
up(i,0,n-1)
minn = min(minn,dp[size][i]);
printf("%d\n",minn);
}
return 0;
}