问题:
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.
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
题意:给你n个字符串,让这n个字符串组成一个最短的公共字符串,题目样例图更易懂。
思路:迭代搜索,从n个字符串中最长的字符串开始搜,一点点的增加,直到找到最佳的答案为止。
代码如下:
#include<stdio.h> #include<string.h> #include<math.h> #include<queue> #include<map> #include<iostream> #include<algorithm> using namespace std; #define inf 0x3f3f3f3f #define mod 1000000007 #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define eps 1e-9 #define lowbit(x) x&(-x) #define PI acos(-1.0) #define N 11 char to[4]= {'A','C','G','T'},s[N][N]; int t,n,pos[N],dep,ans,len[N]; void dfs(int x,int pos[]) { if(x>dep)return ;//当前长度都已经大于预测长度则返回 int maxx=0;//maxx为所有字符串中剩余的长度最长的长度 for(int i=0; i<n; i++)maxx=max(maxx,len[i]-pos[i]); if(x+maxx>dep)return ;//当前长度加上剩余最长长度的和大于预测长度则返回 if(maxx==0){ans=x;return;}//如果剩余的长度都为零则搜索结束 int book[N]; for(int i=0; i<4; i++)//相当于四个方向,每一种情况都尝试一下 { int flag=0; for(int j=0; j<n; j++) if(s[j][pos[j]]==to[i])book[j]=pos[j]+1,flag=1; else book[j]=pos[j]; if(flag)dfs(x+1,book); if(ans)return ; } } int main() { scanf("%d",&t); while(t--) { scanf("%d",&n); ans=0,dep=0; for(int i=0; i<n; i++) { scanf("%s",s[i]); len[i]=strlen(s[i]);//记录每个字符串的长度 dep=max(dep,len[i]);//找到最长的一个字符串的长度,设为初始深度 } while(1) { mem(pos,0);//pos数组对应的是每个字符串匹配过的个数 dfs(0,pos); if(ans)break;//所有的都可以匹配结束 dep++; } printf("%d\n",ans); } }