hdu 1560 DNA sequence(迭代加深搜索)

DNA sequence

Time Limit : 15000/5000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 15   Accepted Submission(s) : 7

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

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.

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

Author

LL

Source

HDU 2006-12 Programming Contest
 
 

使用dfs进行搜索,但限制递归深度。

逐步加深搜索深度,直至找到答案。

主函数中, 限制搜索深度,如果无解,就加深1层深度

强力剪枝: 递归函数中, 首先计算最坏情况下,还需要补充长度:

                为每个DNA序列还未匹配的长度之和(sum)。

              如果现在搜索深度+sum>限定的搜索深度,则返回

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char f[4]={'A','T','G','C'};
int flag,i,t,n,maxlen;
int cnt[50];
char str[10][10];
void dfs(int len,int cnt[])
{
    if (flag || len>maxlen) return;

    int sum=0;
    for(int i=0;i<n;i++)  //关键 :ida*(迭代加深搜索)
        {
           int l=strlen(str[i]);
            sum=max(sum,l-cnt[i]);
        }
    if (sum+len>maxlen) return;
    if (sum==0) {flag=1; return;}

    for(int i=0;i<4;i++)
    {
        char x=f[i];
        int next[50];
        int tflag=0;
        for(int j=0;j<n;j++)
          if (str[j][cnt[j]]==x)
        {
            next[j]=cnt[j]+1;
            tflag=1;
        } else next[j]=cnt[j];
       if (tflag) dfs(len+1,next);  //更新了才说明有效
    }
    return;
}
int main()
{
    scanf("%d",&t);
    for(;t>0;t--)
    {
        scanf("%d",&n);
        maxlen=0;
        for(i=0;i<n;i++)
        {
            scanf("%s",str[i]);
            int l=strlen(str[i]);
            maxlen=max( maxlen,l );
        }
        flag=0;
        memset(cnt,0,sizeof(cnt));
        for(i=0;i<40;i++)
        {
            dfs(0,cnt);
            if (flag) break;
            maxlen++;
        }
        printf("%d\n",maxlen);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/stepping/p/5674923.html