zoukankan      html  css  js  c++  java
  • HDU 1560 DNA sequence A* 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=1560

    仔细读题(!),则可发现这道题要求的是一个最短的字符串,该字符串的不连续子序列中包含题目所给的所有字符串

    因为总共只有40个字符,可以尝试使用A*搜索

    1.存储状态时直接存储40个字符,每个字符4种可能是肯定不行的.

    因为要求的是包含不连续的子序列,所以只需记住当前字符串长度与每个子序列已经包含在当前字符串的长度,

    比如题目中的输入样例

    4

    ACGT

    ATGC

    CGTT

    CAGT

    可以这样存储一个序列

    ATG:len=3,s[0]=1,s[1]=3,s[2]=0,s[3]=0,

    ATC:len=3,s[0]=2,a[1]=2,s[2]=1,s[3]=1,

    又因为只有8个子序列,每个子序列长度不超过5,也就是说可以采用6进制来压缩状态数组.总共不超过6^9=10077696种状态,空间时间都满足

    2.评估函数随便选取了当前未实现的最长长度,2483ms过关

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int maxsta=10077696;
    char str[8][6];
    int l[8];
    int grade[8][6];
    bool vis[maxsta];
    int s[8];
    int n;
    struct status{
        int len,f;
        int sta;
        status():len(0),f(0),sta(0){}
        status(int _len,int _f,int _sta):
            len(_len),f(_f),sta(_sta){}
        bool operator <(status s2)const {
            if(s2.len!=len)return len>s2.len;
            return f>s2.f;
        }
        void tos(){
            int tsta=sta;
            for(int i=n-1;i>=0;i--){
                s[i]=sta%6;
                sta/=6;
            }
            sta=tsta;
        }
        static int tosta(){
            int sta=0;
            for(int i=0;i<n;i++){
                sta*=6;
                sta+=s[i];
            }
            return sta;
        }
        static int calcf(int sta){
            int tmp[8];
            int ans=0;
            for(int i=n-1;i>=0;i--){
                tmp[i]=sta%6;
                sta/=6;
                ans=max(ans,l[i]-tmp[i]);
            }
            return ans;
        }
    };
    priority_queue<status> que;
    int ed;
    int bfs(){
        while(!que.empty())que.pop();
        status st=status(0,status::calcf(0),0);
        char ch[4]={'A','G','C','T'};
        que.push(st);
        vis[0]=true;
        while(!que.empty()){
            status tp=que.top();que.pop();
            if(tp.sta==ed)return tp.len;
            for(int i=0;i<4;i++){
                tp.tos();
                for(int j=0;j<n;j++){
                    if(ch[i]==str[j][s[j]]){
                        s[j]++;
                    }
                }
                int tmpsta=status::tosta();
                if(vis[tmpsta])continue;
                vis[tmpsta]=true;
                if(tmpsta==ed)return tp.len+1;
                que.push(status(tp.len+1,status::calcf(tmpsta),tmpsta));
    
            }
    
        }
        return -1;
    }
    
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            memset(vis,0,sizeof(vis));
            for(int i=0;i<n;i++){
                scanf("%s",str[i]);
                l[i]=strlen(str[i]);
                s[i]=l[i];
            }
            ed=status::tosta();
            int ans=bfs();
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    如何实现网页程序自动登录(java)?
    Java读取股票信息
    (转)如何以32 bit的方式存取SDRAM?
    在DE2上运行uCOSII
    Ubuntu不能上网问题解决之二
    (转)GNU编译器工具链
    (转)Quartus II文件的管理
    (转)avm_m1_writedata[15:0] 與 avm_m1_writedata[31:0]配合avm_m1_byteenable = 4'b0011意義是否一樣?
    (转)如何將編譯結果,統一放在一個目錄下? (QuartusII)
    (转)如何在DE270使用SSRAM?
  • 原文地址:https://www.cnblogs.com/xuesu/p/4412948.html
Copyright © 2011-2022 走看看