题目描述:
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;
}