DNA sequence HDU
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
第一次寫迭代深搜的題
參照了別人的題解
搜尋層數是在主函式增加的 這玩意不用完整展開解答樹省時間
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define clr(a,b) memset(a,b,sizeof(a)); using namespace std; bool flag=0; char map[10][10],str[]="ACGT"; int point[10];//配對成功數量 int num[10];//每行個數 int n; int estimation() //最差估價 { int ans=0; for(int i=0;i<n;i++) { ans=max(ans,num[i]-point[i]);//一層搜可以匹配一個位置字元 如果最大為倆字元 搜兩層就夠了 } return ans; } void dfs(int maxstep) { if(estimation()==0)//估價為0 搜到辣 { flag=true; return; } if(maxstep<estimation())//估價大於最大搜索層數 在主函式裡增加搜尋層數 { return; } int repetition[10];//儲存現場 for(int i=0;i<n;i++) repetition[i]=point[i]; int yes=0; for(int i=0;i<4;i++) { for(int j=0;j<n;j++) { if(map[j][point[j]]==str[i]) { yes=1;//本層有匹配成功的 減一層maxstep搜搜看 這樣就可以不用完整展開解答樹 point[j]++; } } if(yes) { dfs(maxstep-1); if(flag) return; for(int k=0;k<n;k++) point[k]=repetition[k]; } } } int main() { int t; cin>>t; while(t--) { cin>>n; clr(point,0) clr(num,0) clr(map,'\0') flag=0; for(int i=0;i<n;i++) { scanf("%s",map[i]); num[i]=strlen(map[i]); } int result=0; for(int i=0;i<n;i++) result=max(result,num[i]); while(1) { dfs(result); if(flag==true) { cout<<result<<endl; break; } result++; } } return 0; }