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("\n");
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\n",ans);
93 }
94 return 0;
95 }
poj 1699 Best Sequence,布布扣,bubuko.com
时间: 2024-10-11 11:23:12