Match:DNA repair(POJ 3691)

                

                基因修复

  题目大意:给定一些坏串,再给你一个字符串,要你修复这个字符串(AGTC随便换),使之不含任何坏串,求修复所需要的最小步数。

  这一题也是和之前的那个1625的思想是一样的,通过特殊的trie树找到所有的状态然后一个一个枚,具体状态转移的思想可以在1625那里看

  当然了这一题不是像1625那样求总的组合数,这一题也是DP,求的是最小值,那么我们也是一样,统计从合法状态中转移到任何一个状态最小值即可。

  状态转移方程dp[i+1][转移状态]=min(dp[i+1][转移状态],dp[i][当前状态]+s)(当转移状态对应的就是trie的节点,当节点对应的字符等于字符串当前位置的字符,则s为0,否则s为1。)

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <functional>
  4 #include <string.h>
  5 #define MAX 1010
  6 
  7 using namespace std;
  8 
  9 struct node
 10 {
 11     int Num, If_End;
 12     struct node *Fail, *Next[4];
 13 }*root, Mem_Pool[MAX], *Queue[2 * MAX];
 14 
 15 static int sum_node, Hash_Table[256], dp[MAX][MAX];
 16 static char str[MAX], DNA[4] = { 'A', 'G', 'C', 'T' };
 17 
 18 struct node *create_new_node();
 19 int find_min(const int, const int);
 20 void put_DNA_into_hash(void);
 21 void insert(struct node *);
 22 void build_ac_automation(struct node *);
 23 
 24 int main(void)
 25 {
 26     int Disease_Segement_Sum, str_length, case_sum = 1;
 27 
 28     put_DNA_into_hash();
 29     while (~scanf("%d", &Disease_Segement_Sum))
 30     {
 31         if (Disease_Segement_Sum == 0)
 32             break;
 33         sum_node = 0;
 34         node *root = create_new_node();
 35         getchar();
 36         
 37         for (int i = 0; i < Disease_Segement_Sum; i++)
 38             insert(root);
 39         build_ac_automation(root);
 40 
 41         gets(str);
 42         str_length = strlen(str);
 43 
 44         for (int i = 0; i < str_length; i++)
 45         {
 46             fill(dp[i + 1], dp[i + 1] + sum_node, MAX + 1);
 47             for (int j = 0; j < sum_node; j++)
 48             {
 49                 if (Mem_Pool[j].If_End)
 50                     continue;
 51                 for (int k = 0; k < 4; k++)
 52                 {
 53                     int id = Mem_Pool[j].Next[k]->Num;
 54                     if (Mem_Pool[j].Next[k]->If_End)
 55                         continue;
 56                     else if (Hash_Table[str[i]] == k)
 57                         dp[i + 1][id] = find_min(dp[i + 1][id], dp[i][j]);
 58                     else
 59                         dp[i + 1][id] = find_min(dp[i + 1][id], dp[i][j] + 1);
 60                 }
 61             }
 62         }
 63         int ans = MAX + 1;
 64         for (int i = 0; i < sum_node; i++)
 65             ans = find_min(ans, dp[str_length][i]);
 66         if (ans != MAX + 1)
 67             printf("Case %d: %d
", case_sum++, ans);
 68         else
 69             printf("Case %d: -1
",case_sum++);
 70     }
 71     return EXIT_SUCCESS;
 72 }
 73 
 74 int find_min(const int x, const int y)
 75 {
 76     return x < y ? x : y;
 77 }
 78 
 79 struct node *create_new_node(void)
 80 {
 81     node *tmp = &Mem_Pool[sum_node];
 82     tmp->Fail = NULL;
 83     tmp->If_End = 0;
 84     memset(tmp->Next, 0, sizeof(struct node *) * 4);
 85     tmp->Num = sum_node++;
 86     return tmp;
 87 }
 88 
 89 void put_DNA_into_hash(void)
 90 {
 91     for (int i = 0; i<4; i++)
 92         Hash_Table[DNA[i]] = i;
 93 }
 94 
 95 void insert(struct node *root)
 96 {
 97     node *ptr = root;
 98     gets(str);
 99 
100     for (int i = 0; str[i] != ''; i++)
101     {
102         int id = Hash_Table[str[i]];
103         if (ptr->Next[id] == NULL)
104             ptr->Next[id] = create_new_node();
105         ptr = ptr->Next[id];
106     }
107     ptr->If_End = 1;
108 }
109 
110 void build_ac_automation(struct node *root)
111 {
112     int head = 0, tail = 0;
113     root->Fail = NULL;
114     Queue[tail++] = root;
115 
116     while (head != tail)
117     {
118         node *out = Queue[head++];
119         for (int i = 0; i < 4; i++)
120         {
121             if (out->Next[i] != NULL)
122             {
123                 if (out == root)
124                     out->Next[i]->Fail = root;
125                 else
126                 {
127                     out->Next[i]->Fail = out->Fail->Next[i];
128                     if (out->Fail->Next[i]->If_End)
129                         out->Next[i]->If_End = 1;
130                 }
131                 Queue[tail++] = out->Next[i];
132             }
133             else if (out == root)
134                 out->Next[i] = root;
135             else
136                 out->Next[i] = out->Fail->Next[i];
137         }
138     }
139 }

  

原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/5191381.html