题意:
N个序列,只可能由ACGT组成。求最短公共序列。
题解:
暴力打表肯定超时。采用迭代加深搜索可以解决问题。迭代加深搜索其实就是有界的深度优先搜索。可以设置上界从1开始进行搜索(也就是假设最短公共序列的长度为1)。如果当前公共序列长度+某一序列未访问点的长度>上界,则返回Flase,并增加上界。直到所有序列的所有字符都已经被访问为止。
代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<string>
#define INF 1e9
using namespace std;
char seq[10][10];
int len[10];
char dna[4]={'A','C','G','T'};
int dep=1;
int n;
bool ida(int now){
if(now>dep)
return false;
for(int i=0;i<n;i++){
if(strlen(seq[i])-len[i]+now>dep)
return false;
}
bool all=true;
for(int i=0;i<n;i++){
if(len[i]<strlen(seq[i])){
all=false;
break;
}
}
if(all)
return true;
for(int i=0;i<4;i++){
int tmp[10];
memcpy(&tmp,&len,sizeof(len));
bool flag=false;
for(int j=0;j<n;j++){
if(seq[j][len[j]]==dna[i]){
len[j]++;
flag=true;
}
}
if(flag){
if(ida(now+1)){
return true;
}
memcpy(&len,&tmp,sizeof(len));
}
}
return false;
}
int main()
{
int kase;
scanf("%d",&kase);
while(kase--){
memset(len,0,sizeof(len));
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",&seq[i]);
}
dep=1;
while(true){
if(ida(0))
break;
dep++;
}
printf("%d\n",dep);
}
return 0;
}