HDU 1560 DNA sequence

题目描述:

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

解题报告:

1:看别人题解都说什么IDA*算法,我感觉就是剪枝啊,可能蒟蒻还没感觉到这个算法的精妙吧=.=

2:需要明确一点就是:匹配所有串的最小长度是最长串的长度。用一个len和pos数组巧妙的匹配。pos数组表示当前和构造串正在匹配第几个位置。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 40;
char ss[10][10];
ll pos[N], len[N];
char dic[4] = {'A', 'C', 'G', 'T'};
bool dfs(ll d, ll n, ll maxD){
    ll leftNum = 0;
    for(ll i=0; i<n; ++i)
        leftNum = max(leftNum, len[i]-pos[i]);
    if(leftNum == 0)return 1;
    if(leftNum + d > maxD)return 0;
    bool visit[10];
    for(ll i=0; i<4; ++i){
        memset(visit, 0, sizeof(visit));
        for(ll j=0; j<n; ++j)
            if(ss[j][pos[j]] == dic[i])++pos[j], visit[j] = 1;
        if(dfs(d+1, n, maxD))return 1;
        for(ll j=0; j<n; ++j)
            if(visit[j])--pos[j];
    }
    return 0;
}
int main(){
    ll t, n;
    scanf("%lld", &t);
    while(t--){
        scanf("%lld", &n);
        ll maxD = 0;
        for(ll i=0; i<n; ++i){
            scanf("%s", ss[i]);
            ll l = strlen(ss[i]);
            len[i] = l, maxD = max(maxD, l);
        }
        memset(pos, 0, sizeof(pos));
        for(; !dfs(0, n, maxD); ++maxD);
        printf("%lld\n", maxD);
    }
    return 0;
}
发布了190 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jun_____/article/details/104238924