HDU - 1560 DNA sequence
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
IDA*
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;
const char c[10] = "ACGT";
int n;
int pos[maxn]; // pos[i] : 第i个序列正在使用第几个位置
int deep; // 自己构造的DNA序列最小长度
struct node {
char s[maxn]; //DNA的组成
int len; //DNA长度
};
node a[maxn]; //a[i] : 第i个DNA序列
int lenn() { //预估长度
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 + lenn() > deep) //当前长度 + 预计长度 > 构造DNA序列的最小长度(搜索深度)
return 0; //设定的搜索深度并不符合, 加大搜索深度
if(lenn() == 0)//预计长度为0, 即已完成
return 1;
int tmp[maxn];//先将pos保存起来, 一会回溯要用
for(int i = 0; i < 4; i++) {
int flag = 0;
for(int j = 0; j < n; j++) // 保存pos
tmp[j] = pos[j];
for(int j = 0; j < n; j++) { //当前这位符合,则该串正在使用的位置往后移一位
if(a[j].s[pos[j]] == c[i]) {
flag = 1;
pos[j]++;
}
}
if(flag) { //有符合的,则往下搜索
if(dfs(step + 1)) //后面都符合
return 1;
else { //不符合
for(int j = 0; j < n; j++) //回溯
pos[j] = tmp[j];
}
}
}
return 0;
}
void IDAStar() { // IDA* 算法
//迭代加深搜索 : 在不知道迭代深度的前提下,依次探索每次的搜索深度
deep = 0; //自己构造的DNA序列最小长度(搜索深度)
while(true) {
if(dfs(0)) break;
deep++; //设定的搜索深度并不符合条件, 加大搜索深度
}
cout << deep << endl;
}
int main() {
int t;
cin >> t;
while(t--) {
cin >> n;
for(int i = 0; i < n; i++) { //存值
cin >> a[i].s;
a[i].len = strlen(a[i].s);
deep = max(deep, a[i].len);
pos[i] = 0;
}
IDAStar();
}
return 0;
}