HDU 2457. DNA repair (AC自动机+DP)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=2457

题意:
给n个患病DNA串;
给1个DNA串,问最少修改几个(只能用字符AGCT)能使得所有患病DNA串未出现过。

分析:
AC自动机上做动态规划。
就像在Trie上走,去构造一个串;
设f[i][j]表示长度为i,Trie树上节点为j时最少替换的字符数;
则答案为min(f[len][j]), j遍历Trie树上所有节点。

对于每一个状态f[i][j],枚举下一位放置的字符k;
令u=ch[j][k];
若s[i+1]==k,则表明无需替换字符,f[i+1][u]=min(f[i+1][u], f[i][j]);
若s[i+1]!=k,则表明需要替换此位字符,f[i+1][u]=min(f[i+1][u], f[i][j]+1);
一开始对f数组置为无穷大inf;
另外,若一个节点为单词结尾,则其f一定为inf;
若一个节点的fail串上有单词结尾节点,则其f也为inf。

代码:

#include 
using namespace std;
typedef long long llong;
const int tmax=1005;
const int inf=0x3f3f3f3f;
int n;
queue Q;
int index(char x)
{
    if(x=='A') return 0;
    if(x=='G') return 1;
    if(x=='C') return 2;
    return 3;
}
struct AC{
    int ch[tmax][4],f[tmax],cnt,last[tmax];
    bool val[tmax];
    void init()
    {
        cnt=0;
        memset(ch,0,sizeof(ch));
        memset(val,0,sizeof(val));
        memset(f,0,sizeof(f));
        memset(last,-1,sizeof(last));
        return;
    }
    void insert(char *s)
    {
        int len=strlen(s),u=0,id;
        for(int i=0;i

你可能感兴趣的:(AC自动机,字符串,动态规划)