DNA sequence
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 721 Accepted Submission(s): 349
Problem Description
The twenty-first century is a biology-technology developing century. We know that a gene is made of DNA. The nucleotide bases from which DNA is built are A(adenine), C(cytosine), G(guanine), and T(thymine). Finding the longest common subsequence between DNA/Protein sequences is one of the basic problems in modern computational molecular biology. But this problem is a little different. Given several DNA sequences, you are asked to make a shortest sequence from them so that each of the given sequence is the subsequence of it.
For example, given "ACGT","ATGC","CGTT" and "CAGT", you can make a sequence in the following way. It is the shortest but may be not the only one.
For example, given "ACGT","ATGC","CGTT" and "CAGT", you can make a sequence in the following way. It is the shortest but may be not the only one.
Input
The first line is the test case number t. Then t test cases follow. In each case, the first line is an integer n ( 1<=n<=8 ) represents number of the DNA sequences. The following k lines contain the k sequences, one per line. Assuming that the length of any sequence is between 1 and 5.
Output
For each test case, print a line containing the length of the shortest sequence that can be made from these sequences.
Sample Input
1 4 ACGT ATGC CGTT CAGT
Sample Output
8题意:很容易看懂思路:dfs枚举所有情况,由于深度未知,所以可以利用迭代加深搜索的方式。感想:开始用朴素dfs算法 果断超时 于是想到IDA* 由于一个数组定义为全局变量了 debug我好久代码:#include <iostream> #include <cstdio> #include <cstring> #define maxn 10 using namespace std; int n,ans,depth; int len[maxn],p[maxn]; char s[maxn][maxn]; char dx[]={'A','C','G','T'}; int geth() // A*函数 得到最小需要几个字符来满足条件 { int i,j,t=-1,tt; for(i=1;i<=n;i++) { tt=len[i]-p[i]; if(t<tt) t=tt; } return t; } bool dfs(int pos) { int i,j,h,flag; int tmp[maxn]; // 开始把这个定义为全局变量了 debug我好久 ╮(╯▽╰)╭ h=geth(); // 得到最小需要几个字符来满足条件 if(pos+h>depth) return false ; // 如果加上最小所需字符都不能满足条件则剪枝 if(h==0) { ans=pos; return true ; } for(i=1;i<=n;i++) tmp[i]=p[i]; for(i=0;i<4;i++) { flag=0; // 用来剪枝 for(j=1;j<=n;j++) { if(s[j][p[j]]==dx[i]) { flag=1; p[j]++; } } if(!flag) continue ; // 如果p[j]都没变化 则加的字母没用 剪枝 if(dfs(pos+1)) return true ; for(j=1;j<=n;j++) p[j]=tmp[j]; } return false ; } int main() { int i,j,t; scanf("%d",&t); while(t--) { scanf("%d",&n); depth=-1; for(i=1;i<=n;i++) { scanf("%s",s[i]); len[i]=strlen(s[i]); p[i]=0; if(depth<len[i]) depth=len[i]; } while(!dfs(0)) depth++; // IDA* 每次限定深度 printf("%d\n",ans); } return 0; }