HDU 1560 DNA sequence(IDA*)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560

题目大意:给出n个字符串,让你找一个字符串使得这n个字符串都是它的子串,求最小长度。

解题思路:迭代加深搜索,迭代加深搜索,就是限制DFS的深度deep,若搜不到答案,则加深深度,重新搜索,这样就防止了随着深度不断加深而进行的盲目搜索。这题的迭代深度deep以这n个子串中的最长长度作为起点,不断+1,知道找到符合条件的字符串。每次DFS的时候,都要判断一下,当前的深度+最少还有加深的深度是否大于限制的长度,若是,则返回上一层。

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<queue>
 5 #include<string>
 6 using namespace std; 
 7 typedef long long LL;
 8 const int inf=0x3f3f3f3f;
 9 
10 int n,deep,ans;
11 char DNA[5]="ACGT";
12 char str[10][10];
13 
14 int Max(int a,int b){
15     return a>b?a:b;
16 }
17 
18 void dfs(int index,int len[]){
19     if(ans!=-1)
20         return;
21     int h=0;//接下来至少还要增加的字符长度 
22     for(int i=1;i<=n;i++)
23         h=Max(h,strlen(str[i])-len[i]);
24     if(h==0){
25         ans=index;
26         return; 
27     }
28     if(h+index>deep)//当前深度+预测最小深度>限制深度 
29         return;
30     int pos[10]={0};
31     for(int i=0;i<4;i++){    
32         bool flag=false;
33         for(int j=1;j<=n;j++){
34             if(str[j][len[j]]==DNA[i]){
35                 flag=true;
36                 pos[j]=len[j]+1;
37             }
38             else
39                 pos[j]=len[j];
40         }
41         if(flag&&index+1<=deep)//剪枝,!flag说明无论加什么都无法使n个字符串都为子串
42             dfs(index+1,pos);
43     }
44 }
45 
46 int main(){
47     int t;
48     scanf("%d",&t);
49     while(t--){
50         scanf("%d",&n);
51         int mlen=0;//最大子串长度 
52         for(int i=1;i<=n;i++){
53             scanf("%s",str[i]);
54             mlen=Max(strlen(str[i]),mlen);
55         }
56         
57         int pos[10]={0};//n个字符串当前匹配到的位置 
58         deep=mlen;
59         ans=-1;
60         while(1){
61             dfs(0,pos);
62             if(ans!=-1)
63                 break;
64             deep++;
65         }
66         printf("%d\n",ans);
67     }
68     return 0;
69 } 

 

posted @ 2017-09-18 23:33  Yeader  阅读(142)  评论(0编辑  收藏  举报