原题链接

考察:IDA*

完全没想到啊....但通过这道题感觉dfs本质就是枚举吧...所以这道题dfs需要一直枚举AGCT,直到所有位置都匹配.

思路:

       但是光枚举肯定会TLE的,所以需要剪枝.总共只有8个字符串,每个只有5个字符.最多(不可能达到)要40个字符.所以可以考虑迭代加深.我们在匹配时还可以计算最少还有多少到终态.所以又可以加上预估函数.总的算法就是IDA*.

       枚举方法:不停地枚举ATGC直到所有字符串全部被覆盖.对于每一个枚举的字符,用match[i]标识第i个字符串匹配到第match[i]个字符.不停dfs回溯可以枚举所有方法.

       A*函数:

       策略一:对于每个串取未匹配长度的最大值.即预估函数返回值.858ms

       策略二:统计每个串未匹配长度需要的AGCT数量.每个取最大值再累加. 31ms

 1 #include <iostream> 
 2 #include <cstring>
 3 #include <map>
 4 using namespace std;
 5 const int N = 6,M = 10,S = 30;
 6 map<char,int> mp;
 7 int n,len[M],match[M],deep,index[S],cnt[N],tmp[N];
 8 char s[M][N],DNA[6] = "ATGC";
 9 int h()
10 {
11 //    memset(cnt,0,sizeof cnt);
12     memset(tmp,0,sizeof tmp);
13     for(int i=1;i<=n;i++)
14     {
15         for(int j=match[i]+1;j<=len[i];j++) 
16           cnt[index[s[i][j]-'A']]++;
17         for(int j=0;j<4;j++)
18             tmp[j] = max(tmp[j],cnt[j]),cnt[j] = 0; 
19     }
20     int res = 0;
21     for(int i=0;i<4;i++) res+=tmp[i];
22     return res;
23 }
24 bool dfs(int step)
25 {
26     int val = h();
27     if(!val) return 1;
28     if(step+val>deep) return 0; 
29     int b[M];
30     for(int i=0;i<4;i++)//枚举下一个字符 
31     {
32         memcpy(b,match,sizeof match);
33         bool ok = 0;
34         for(int j=1;j<=n;j++)//枚举每一个字符串要匹配的位置是否与该字符匹配 
35            if(s[j][match[j]+1]==DNA[i])
36            {
37                      match[j]++;//
38                      ok = 1;
39            }
40         if(ok&&dfs(step+1)) return 1;
41         memcpy(match,b,sizeof b);
42     }
43     return 0;
44 }
45 int main()
46 {
47     int T;
48     scanf("%d",&T);
49     for(int i=0;i<4;i++) index[DNA[i]-'A'] = i;
50     while(T--)
51     {
52         scanf("%d",&n);
53         deep = 0;
54         for(int i=1;i<=n;i++) 
55         {
56             scanf("%s",s[i]+1);
57             match[i] = 0;
58             len[i] = strlen(s[i]+1);
59             deep = max(deep,len[i]);
60         }
61         while(!dfs(0)) deep++;
62         printf("%d\n",deep);
63     }
64     return 0;
65 }