題目鏈接

題意 : 將幾個片段如圖所示方法縮成一個序列,求出最短這個序列。

思路 : 其實我也不知道怎麼做。。。。。看網上都用了DP。。。。。但是我不會。。。。。這個DP不錯,還有用KMP+状压DP做的

 1 //1699
 2 #include <iostream>
 3 #include <stdio.h>
 4 #include <string.h>
 5 #include <string>
 6 
 7 using namespace std;
 8 
 9 string str[13] ;
10 int dp[33][33],ans ,n,vis[23];
11 
12 void f(int i,int j)
13 {
14     int len1 = str[i].size() ;
15     int len2 = str[j].size() ;
16     int s = 0 ;
17     for(int k = 0 ; k <= len1 && k <= len2 ; k++)
18     {
19         bool flag = true ;
20         for(int h = 0 ; h < k ; h++)
21         {
22             if(str[i][len1-k+h] != str[j][h])
23             {
24                 flag = false ;
25                 break ;
26             }
27         }
28         if(flag == true)
29             s = k ;
30     }
31     dp[i][j] = len2-s ;
32 }
33 
34 void dfs(int now,int ceng,int len)
35 {
36     if(len >= ans) return  ;
37     if(ceng == n-1) ans = min(ans,len) ;
38     for(int i = 1 ; i <= n ; i++)
39     {
40         if(!vis[i])
41         {
42             vis[i] = 1 ;
43             dfs(i,ceng+1,len+dp[now][i]) ;
44             vis[i] = 0 ;
45         }
46     }
47 }
48 int main()
49 {
50     int T;
51     scanf("%d",&T) ;
52     while(T--)
53     {
54         scanf("%d",&n) ;
55         for(int i = 1 ; i <= n ; i++)
56             cin>>str[i] ;
57         for(int i = 1 ; i <= n ; i++)
58             for(int j = 1 ; j <= n ; j++)
59                 if(i != j) f(i,j) ;
60         memset(vis,0,sizeof(vis)) ;
61         ans = 99999999 ;
62         for(int i = 1 ; i <= n ; i++)
63         {
64             vis[i] = 1 ;
65             dfs(i,0,str[i].size()) ;
66             vis[i] = 0 ;
67         }
68         printf("%d\n",ans) ;
69     }
70     return 0;
71 }
View Code

 

posted on 2014-05-26 15:35  枫、  阅读(241)  评论(0编辑  收藏  举报