DNA sequence
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3118 Accepted Submission(s): 1518
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.
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
题意:
给定几个DNA序列,你要求一个最短的序列,使每一个给定的序列都是它的子序列。
比如给出的序列为"ACGT","ATGC","CGTT"和"CAGT",你可以构造一个这样的序列:"ACAGTGCT",它是最短的一个序列,但不是唯一的。
子序列:可以拆分开,不一定要连续
保证有解,暴力搜索序列的每一位是什么,枚举长度, 注意记录每一个串匹配到哪里了。
剪枝条件:和每一串的失配数量,如果最大的失配数已经超过(枚举长度-当前长度)就退出。
Code:
Status | Accepted |
---|---|
Time | 2464ms |
Memory | 1680kB |
Length | 1062 |
Lang | G++ |
Submitted | 2017-10-05 19:34:39 |
Shared |
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int N, lim;
char S[10][6];
char A[50];
char *d = "ATCG";
bool flg;
void Dfs(int now, int *p){
if(now > lim) return ;
int cnt = 0;
for(int i = 1; i <= N; ++ i)
cnt = max(S[i][0] - p[i], cnt);
if(cnt == 0) {flg = 1;return ;}
if(now + cnt > lim) return ;
for(int i = 0; i < 4; ++ i){
A[now] = d[i];
int tmp[10];
for(int i = 1; i <= N; ++ i)
if(S[i][p[i] + 1] == A[now]) tmp[i] = p[i] + 1;
else tmp[i] = p[i];
Dfs(now + 1, tmp);
if(flg) return ;
}
}
int main(){
int T;
scanf("%d", &T);
while(T --){
flg = 0;
scanf("%d", &N);
for(int i = 1; i <= N; ++ i) scanf("%s", S[i] + 1), S[i][0] = strlen(S[i] + 1);
int p[10];
for(lim = 1; ; ++ lim){
memset(p, 0, sizeof p );
Dfs(0, p);
if(flg) break;
}
printf("%d\n", lim);
}
return 0;
}