Description
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.
Input
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.
Output
For each test case, output an integer indicating the length of the shortest string containing all these strings.
Sample Input
1
2
ABCD
BCDABC
Sample Output
7
HINT
Source
题意:n个串,求出一个能包含这n个串的最短串的长度
思路:由于数据不大,所以我们可以暴力,首先求出字符串两两合并的情况,再使用状态压缩暴力枚举求出结果
#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;
}