• POJ1699 Best Sequence(AC自动机+状压DP)


    题目,求包含所有的给定的n个DNA片段的序列的最短长度。

    AC自动机上的DP题。

    • dp[S][u]表示已经包含的DNA片段集合为S,且当前后缀状态是自动机第u个结点的最短长度
    • dp[0][0]=0
    • 我为人人+队列轻松转移。。
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 #define INF (1<<30)
     7 int tn,ch[222][4],fail[222],flag[222];
     8 int idx[128];
     9 void insert(char *s,int k){
    10     int x=0;
    11     for(int i=0; s[i]; ++i){
    12         int y=idx[s[i]];
    13         if(ch[x][y]==0) ch[x][y]=++tn;
    14         x=ch[x][y];
    15     }
    16     flag[x]|=(1<<k);
    17 }
    18 void getfail(){
    19     memset(fail,0,sizeof(fail));
    20     queue<int> que;
    21     for(int i=0; i<4; ++i){
    22         if(ch[0][i]) que.push(ch[0][i]);
    23     }
    24     while(!que.empty()){
    25         int x=que.front(); que.pop();
    26         for(int i=0; i<4; ++i){
    27             if(ch[x][i]){
    28                 que.push(ch[x][i]);
    29                 fail[ch[x][i]]=ch[fail[x]][i];
    30                 flag[ch[x][i]]|=flag[ch[fail[x]][i]];
    31             }else ch[x][i]=ch[fail[x]][i];
    32         }
    33     }
    34 }
    35 struct Node{
    36     int s,x;
    37     Node(int _s,int _x):s(_s),x(_x){}
    38 };
    39 int d[1<<10][222],vis[1<<10][222];
    40 int main(){
    41     idx['A']=0; idx['C']=1; idx['G']=2; idx['T']=3;
    42     int t,n;
    43     char str[22];
    44     scanf("%d",&t);
    45     while(t--){
    46         tn=0;
    47         memset(ch,0,sizeof(ch));
    48         memset(flag,0,sizeof(flag));
    49         scanf("%d",&n);
    50         for(int i=0; i<n; ++i){
    51             scanf("%s",str);
    52             insert(str,i);
    53         }
    54         getfail();
    55         for(int i=0; i<(1<<n); ++i){
    56             for(int j=0; j<=tn; ++j) d[i][j]=INF;
    57         }
    58         d[0][0]=0;
    59         memset(vis,0,sizeof(vis));
    60         vis[0][0]=1;
    61         queue<Node> que;
    62         que.push(Node(0,0));
    63         while(!que.empty()){
    64             int s=que.front().s,x=que.front().x; que.pop();
    65             for(int i=0; i<4; ++i){
    66                 int ns=s|flag[ch[x][i]],nx=ch[x][i];
    67                 if(d[ns][nx]>d[s][x]+1){
    68                     d[ns][nx]=d[s][x]+1;
    69                     if(!vis[ns][nx]){
    70                         vis[ns][nx]=1;
    71                         que.push(Node(ns,nx));
    72                     }
    73                 }
    74             }
    75             vis[s][x]=0;
    76         }
    77         int res=INF;
    78         for(int i=0; i<=tn; ++i){
    79             res=min(res,d[(1<<n)-1][i]);
    80         }
    81         printf("%d
    ",res);
    82     }
    83     return 0;
    84 } 
  • 相关阅读:
    Eclipse汉化后怎么改回英文版 (中文 改 英文)
    解决android中Layout文件下的xml文件配好后,R类中不能自动生成相应代码
    Android SDK离线安装
    Windows环境下Android Studio v1.0安装教程
    Eclipse调试Bug的七种常用技巧
    博客开通了
    Android常见的按钮监听器实现方式
    用setTimeout实现在DOM上(通常是菜单栏)鼠标停留一段时间才执行相应的操作
    Javascript模块模式学习分享
    Oracle数据库逻辑存储结构管理
  • 原文地址:https://www.cnblogs.com/WABoss/p/5285573.html
Copyright © 2020-2023  润新知