DNA sequence HDU

题目大意:有n个DNA序列,构造一个新的序列,使得这n个DNA序列都是它的子序列,然后输出最小长度。

题解:第一次接触IDA*算法,感觉~~好暴力!!思路:维护一个数组pos[i],表示第i个串该匹配第pos[i]个元素。一共有四种可能,A,C,G,T,依次枚举,如果说A和n个串中的第j个串匹配,就直接就pos[j]++就行了,然后进入下一层,如果说最终没有成功构造,还有进行回溯,所以每一层我们都要维护一个数组来记录pos的值方便回溯。

具体实现和注释都在code中了,应该不难理解.

code:

#include<bits/stdc++.h>
using namespace std;
const int N=20;
int len[N];
string s[N];
int n;
string st="AGCT";
int pos[N];//表示第i个字符串匹配该第pos[i]个位置 
int get(){//用来表示当前最少要走多少部步 
    int ans=0;
    for(int i=1;i<=n;i++)
        ans=max(ans,len[i]-pos[i]);
    return ans;
}
bool dfs(int step,int depth){
    if(step+get()>depth) return 0;//长度不够 
    if(!get()) return 1;//全部匹配成功 
    int temp[20];//回溯的时候会用到 
    for(int i=1;i<=n;i++) temp[i]=pos[i];
    for(int i=0;i<4;i++){//A C G T,依次枚举匹配 
        bool flag=0;//用来记录第j个string,pos[j]处的字符串是否匹配成功. 
        for(int j=1;j<=n;j++){
            if(s[j][pos[j]]==st[i]){
                flag=1;
                pos[j]++;
            }
        }
        if(flag){//flag=1,说明至少有一个串和st[i]匹配. 
            if(dfs(step+1,depth)) return 1;
            for(int i=1;i<=n;i++) pos[i]=temp[i];
        }
    }
    return 0;
}
int main(){
    ios::sync_with_stdio(0);
    int t;
    cin>>t;
    while(t--){
        memset(len,0,sizeof len);
        memset(pos,0,sizeof pos);
        cin>>n;
        string c;
        int maxn=0;
        for(int i=1;i<=n;i++){
            cin>>s[i];
            len[i]=s[i].size(); 
            maxn=max(maxn,len[i]);
        }
        while(1){
            if(dfs(0,maxn)) break;
            maxn++;
        }
        cout<<maxn<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Accepting/p/12713601.html