zoukankan      html  css  js  c++  java
  • poj 3769 DNA repair

    /*2016.01.22
     *poj3769DNArepair.cpp
     * ac自动机+dp, 多模式匹配
     * 考虑存在这样的修改满足题意,则沿着修改后的字符串进行状态转移每一步都
     * 将到达安全的状态(不含病毒串为子串),满足最优子结构。假设:
     * c 为从状态from到to的字符,dp[i][to]表示第i步到达to状态最少需要改变的字符数,
     * 状态from 和 to 都要是安全的:
     * dp[i][to] = min(dp[i-1][from] + c != s[i], dp[i][to])
     */

      1 #include <cstdio>
      2 #include <map>
      3 #include <string.h>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 const int MAX = 1010, SZ = 4;
      8 int dp[MAX], tmp[MAX], cur;
      9 map<char, int> c2n;
     10 
     11 class node {
     12 public:
     13     int unsafe;
     14     node *next[SZ], *fail;
     15     void init(){
     16         memset(this, 0, sizeof(node));
     17     }
     18 }ac[MAX], *q[MAX], *rt;
     19 
     20 void Insert(char *s){
     21     int i=0, idx;
     22     node *p=rt;
     23     for(i=0; s[i]; ++i){
     24         idx = c2n[s[i]];
     25         if(p->next[idx] == NULL){
     26             p->next[idx] = &ac[cur];
     27             ac[cur++].init();
     28         }
     29         p = p->next[idx];
     30     }
     31     p->unsafe = 1;
     32 }
     33 //v1:
     34 // void BuildAC(){
     35 //     int h = 1, t = 0, i;
     36 //     node *nd;
     37 //     q[0] = rt;
     38 //     rt->fail = NULL;
     39 //     while(t < h){
     40 //         for(i=0; i<SZ; ++i){
     41 //             if(q[t]->next[i] == NULL) continue;
     42 //             if(q[t] == rt) q[t]->next[i]->fail = rt;
     43 //             else {
     44 //                 nd = q[t]->fail;
     45 //                 while(nd != NULL && nd->next[i] == NULL) nd = nd->fail;
     46 //                 if(nd == NULL) q[t]->next[i]->fail = rt;
     47 //                 else {
     48 //                     q[t]->next[i]->fail = nd->next[i];
     49 //                     q[t]->next[i]->unsafe |= nd->next[i]->unsafe;
     50 //                 }
     51 //             }
     52 //             q[h++] = q[t]->next[i];
     53 //         }
     54 //         ++t;
     55 //     }
     56 // }
     57 //v2:
     58 void BuildAC(){
     59     int h=1, t=0, i;
     60     node *nd;
     61     q[0] = rt;
     62     rt->fail = NULL;
     63     while(t < h){
     64         for(i=0; i<SZ; ++i){
     65             if(q[t]->next[i] != NULL) q[h++] = q[t]->next[i];
     66             if(q[t] == rt){
     67                 if(q[t]->next[i] == NULL) q[t]->next[i] = rt;
     68                 else q[t]->next[i]->fail = rt;
     69             }
     70             else {
     71                 nd = q[t]->fail;
     72                 if(q[t]->next[i] == NULL) q[t]->next[i] = nd->next[i];
     73                 else {
     74                     q[t]->next[i]->fail = nd->next[i];
     75                     q[t]->next[i]->unsafe |= nd->next[i]->unsafe;
     76                 }
     77             }
     78         }
     79         ++t;
     80     }
     81 }
     82 int Solve(char *s){
     83     int *bef = dp, *aft = tmp, i, j, k, n = strlen(s);
     84     node *nd;
     85     memset(bef, 0, sizeof(dp));
     86     for(i=0; i<n; ++i){
     87         memset(aft, 0x4, sizeof(dp));
     88         for(j=0; j<cur; ++j)
     89             if(ac[j].unsafe == 0){
     90                 for(k=0; k<SZ; ++k){
     91                     int idx = ac[j].next[k] - rt;
     92                     // nd = &ac[j];
     93                     // while(nd != rt && nd->next[k]==NULL) nd = nd->fail;
     94                     // if(nd->next[k] != NULL) idx = nd->next[k] - rt;
     95                     if(ac[idx].unsafe == 0){
     96                         aft[idx] = min(aft[idx], bef[j]+(c2n[s[i]]!=k));
     97                     }
     98                 }
     99                 //第一次动归从根出发
    100                 if(i == 0) break;
    101             }
    102         swap(aft, bef);
    103     }
    104     n = MAX;
    105     for(i=0; i<cur; ++i)
    106         if(ac[i].unsafe == 0)
    107             n = min(n, bef[i]);
    108     return n == MAX ? -1 : n;
    109 }
    110 
    111 int main() {
    112     int i, n, t=0;
    113     char s[MAX];
    114     rt = ac;
    115     c2n['A'] = 0; c2n['C'] = 1; c2n['G'] = 2; c2n['T'] = 3;
    116     while(scanf("%d", &n), n){
    117         cur = 1;
    118         ac[0].init();
    119         for(i=0; i<n; ++i){
    120             scanf("%s", s);
    121             Insert(s);
    122         }
    123         scanf("%s",s);
    124         BuildAC();
    125         printf("Case %d: %d
    ", ++t, Solve(s));
    126     }
    127 }

    参考:

    http://blog.sina.com.cn/s/blog_6635898a0102e1ig.html

  • 相关阅读:
    win7为IIS7添加程序映射
    【整理】在一亿个数中寻找出现频率最多的4个 <转>
    优化SQL Server数据库的几个大招<转>
    最长单调子序列(DP)
    详细解说 STL 排序
    获取word中的原始大小图片
    MD5 算法实现(c++)
    udp 通信中的端口问题
    Yacc 与 Lex 快速入门
    HDOJ (HDU) 1561 The more, The Better (树形DP)
  • 原文地址:https://www.cnblogs.com/yyf2016/p/5155621.html
Copyright © 2011-2022 走看看