http://poj.org/problem?id=1699
题意:给你n个长度为L的序列,求包含这几个序列的最短长度。
先预处理每两个序列之间的关系,然后dfs枚举就行。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 500 5 using namespace std; 6 const int inf=1<<30; 7 8 char str[maxn][maxn]; 9 int c[maxn][maxn]; 10 int n; 11 bool vis[maxn]; 12 13 int make_l(int s,int t) 14 { 15 int cnt=0; 16 int k1=strlen(str[s]); 17 int k2=strlen(str[t]); 18 for(int i=0; i<=k1&&i<=k2; i++) 19 { 20 bool flag=false; 21 for(int j=0; j<i; j++) 22 { 23 if(str[s][k1-i+j]!=str[t][j]) 24 { 25 flag=true; 26 break; 27 } 28 } 29 if(!flag) cnt=i; 30 } 31 return k1-cnt; 32 } 33 34 int dfs(int src,int step) 35 { 36 int sum=inf; 37 if(step==n) 38 { 39 int kl=strlen(str[src]); 40 return kl; 41 } 42 for(int i=1; i<=n; i++) 43 { 44 if(!vis[i]) 45 { 46 vis[i]=true; 47 int sum1=c[src][i]; 48 sum1+=dfs(i,step+1); 49 vis[i]=false; 50 sum=min(sum,sum1); 51 } 52 } 53 return sum; 54 } 55 56 int main() 57 { 58 int t1; 59 scanf("%d",&t1); 60 while(t1--) 61 { 62 scanf("%d",&n); 63 for(int i=1; i<=n; i++) 64 { 65 scanf("%s",str[i]); 66 } 67 memset(c,0,sizeof(c)); 68 for(int i=1; i<=n; i++) 69 { 70 for(int j=1; j<=n; j++) 71 { 72 if(i==j) continue; 73 c[i][j]=make_l(i,j); 74 } 75 } 76 /*for(int i=1; i<=n; i++) 77 { 78 for(int j=1; j<=n; j++) 79 { 80 printf("%d ",c[i][j]); 81 } 82 printf(" "); 83 }*/ 84 memset(vis,false,sizeof(vis)); 85 int ans=inf; 86 for(int i=1; i<=n; i++) 87 { 88 vis[i]=true; 89 ans=min(ans,dfs(i,1)); 90 vis[i]=false; 91 } 92 printf("%d ",ans); 93 } 94 return 0; 95 }