【HDU - 1560】DNA sequence (dfs+回溯)

DNA sequence

直接中文了

题目描述

21世纪是生物科技飞速发展的时代。我们都知道基因是由DNA组成的,而DNA的基本组成单位是A,C,G,T。在现代生物分子计算中,如何找到DNA之间的最长公共子序列是一个基础性问题。 但是我们的问题不是那么简单:现在我们给定了数个DNA序列,请你构造出一个最短的DNA序列,使得所有我们给定的DNA序列都是它的子序列。 例如,给定"ACGT","ATGC","CGTT","CAGT",你可以构造的一个最短序列为"ACAGTGCT",但是需要注意的是,这并不是此问题的唯一解。

输入

第一行含有一个数t,代表数据组数。 每组数据的第一行是一个数n,代表给定的DNA序列数量;接下来的n行每行一个字符串s,代表给定的n个DNA序列。 1<=n<=8,1<=|s|<=5

输出

对于每一组数据,输出一行中含有一个数,代表满足条件的最短序列的长度。

样例输入

1
4
ACGT
ATGC
CGTT
CAGT

样例输出

8

题目链接

https://vjudge.net/problem/HDU-1560

给出N个DNA序列,要求出一个包含这n个序列的最短序列是多长,直接dfs吧

AC代码

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 10
using namespace std;
int pos[Maxn];//pos[i]  第i个序列正在使用第几个位置
int T,n;
int deep;//自己构造的DNA序列最小长度
char c[10] = "ACGT";
struct node
{
    char ch[Maxn];      //DNA的组成
    int len;     //DNA长度
};
node a[Maxn];//a[i]  第i个DNA序列
int init()//预估长度
{
    int ans=0;
    for(int i=0;i<n;i++)//总长度-正在使用的位置=剩下还没用的位置 即预计长度
        ans=max(ans,a[i].len-pos[i]);
    return ans;
}
int dfs(int step)
{
    if(step+init()>deep)//预计长度+当前长度>构造DNA序列的最小长度
        return 0;
    if(init()==0)//预计长度为0,即已完成
        return 1;
    int pre[Maxn];//先将pos保存起来,一会回溯要用
    for(int i=0;i<4;i++)
    {
        int f=0;
        for(int j=0;j<n;j++)//保存pos
            pre[j]=pos[j];
        for(int j=0;j<n;j++)//当前这位符合,则该串的位置往后移一位
        {
            if(a[j].ch[pos[j]]==c[i])
            {
                f=1;
                pos[j]++;
            }
        }
        if(f)
        {
            if(dfs(step+1))//有符合的,则往下搜索
                return 1;
            for(int j=0;j<n;j++)//回溯
                pos[j]=pre[j];
        }
    }
    return 0;
}
int main()
{
    cin>>T;
    while(T--)
    {
        deep=0;//自己构造的DNA序列最小长度
        cin>>n;
        for(int i=0;i<n;i++)//存值
        {
            cin>>a[i].ch;
            a[i].len=strlen(a[i].ch);
            deep=max(deep,a[i].len);
            pos[i]=0;
        }
        while(1)
        {
            if(dfs(0))
                break;
            deep++;
        }
        cout<<deep<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/sky-stars/p/11219615.html

时间: 2024-11-07 11:06:10

【HDU - 1560】DNA sequence (dfs+回溯)的相关文章

HDU 1560 DNA sequence(DNA序列)

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-size: 10.5000pt } h1 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: center; font-family: 宋体; color: rgb(26,92,200); font-weight: bold; fo

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

HDU 1560 DNA sequence(IDA*)

DNA sequence Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6042    Accepted Submission(s): 2735 Problem Description The twenty-first century is a biology-technology developing century. We kno

HDU - 1560 DNA sequence

给你最多8个长度不超过5的DNA系列,求一个包含所有系列的最短系列. 迭代加深的经典题.(虽然自己第一次写) 定一个长度搜下去,搜不出答案就加深大搜的限制,然后中间加一些玄学的减枝 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<

HDU 1560 DNA sequence A* 难度:1

http://acm.hdu.edu.cn/showproblem.php?pid=1560 仔细读题(!),则可发现这道题要求的是一个最短的字符串,该字符串的不连续子序列中包含题目所给的所有字符串 因为总共只有40个字符,可以尝试使用A*搜索 1.存储状态时直接存储40个字符,每个字符4种可能是肯定不行的. 因为要求的是包含不连续的子序列,所以只需记住当前字符串长度与每个子序列已经包含在当前字符串的长度, 比如题目中的输入样例 4 ACGT ATGC CGTT CAGT 可以这样存储一个序列

HDOJ 1560 DNA sequence 状压dp 或 IDA*

http://acm.hdu.edu.cn/showproblem.php?pid=1560 题意: 给不超过8个子串,每个子串最多5位,且都只包含ATCG,求最短的母串长度. 分析: 又是上个月写的,所以有点忘了..正解是IDA*.然后可以状压dp,记忆化搜索.dp[i],i用6进制表示,每位表示对应的子串匹配那么多长度所需要的最短母串长度.比如两个子串,13=2*6^1+1*6^0,dp[13]就表示第一个串匹配了第一位,第二个串匹配前两位所需要的最短母串长度. 状态讲完了,不过实际上程序里

POJ1699 HDU 1560 Best Sequence(AC自动机 最短路)

曾写过迭代加深搜索的方法,现在使用在AC自动上跑最短路的方法 dp[i][j]表示状态为到节点i,模式串是否包含的状态为j的最短串的长度,则状态转移方程为: dp[nx][ny] = min(dp[x][y] + 1) , 其中nx为x后继结点,ny为从y转移过来的新状态,更新时加入队列 #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<al

DNA sequence HDU - 1560

DNA sequence Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4217    Accepted Submission(s): 2020 Problem Description The twenty-first century is a biology-technology developing century. We kno

HDU 1015 dfs回溯

题目真长.....看了好长时间才看懂.. 就是给你一个32位数字和一个最多15个字符的字符串,从字符串中选出5个字符,若满足题中给的那个式子,输出字典序最大的那5个字符,若不满足,输出no solution. 为了解决字典序问题,在输入字符串后,把字符串按从大到小排一下序,搜索一下若满足条件输出即可. 贴代码. 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <