HDU

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

题意:

从n个串中找出一个最短的公共串,,该公共串对于n个字符串不要求连续,即只要保持相对顺序就好。

思路:

用迭代加深搜索,所谓迭代加深搜索,就是限制DFS的深度,若搜不到答案,则加深深度,重新搜索,这样就防止了随着深度不断加深而进行的盲目搜索,而且,对于这种求最短长度之类的题目,只要找到可行解,即是最优解了。同时注意剪枝,每次DFS的时候,都要判断一下,当前的深度+最少还有加深的深度是否大于限制的长度,若是,则退回上一层状态。

#include<bits/stdc++.h>
using namespace std;

char str[10][10];//记录n个字符串
int n, ans, deep, Size[10];
char DNA[4] = { 'A','C','G','T' };//4种可能性

void dfs(int cnt,int len[]) {
    if (cnt > deep)return;//大于了最大深度
    int maxx = 0;//预计还要匹配的字符串的最大长度
    for (int i = 0; i < n; ++i) {
        int t = Size[i] - len[i];
        if (t > maxx)
            maxx = t;
    }
    if (maxx == 0) {//条件全部满足即为最优解
        ans = cnt; return;
    }
    if (cnt + maxx > deep)return;
    for (int i = 0; i < 4; ++i) {
        int pos[10], flag = 0;
        for (int j = 0; j < n; j++)
        {
            if (str[j][len[j]] == DNA[i])
            {
                flag = 1;
                pos[j] = len[j] + 1;
            }
            else
                pos[j] = len[j];
        }
        if (flag)
            dfs(cnt + 1, pos);
        if (ans != -1)
            break;
    }
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        int maxn = 0;
        for (int i = 0; i < n; ++i) {
            cin >> str[i];
            Size[i] = strlen(str[i]);
            if (Size[i] > maxn)
                maxn = Size[i];
        }
        ans = -1; deep = maxn;
        int pos[10] = { 0 };//记录n个字符串目前匹配到的位置
        while (1) {
            dfs(0, pos);
            if (ans != -1)break;
            ++deep;
        }
        cout << ans << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/RioTian/p/13110340.html