HDU 2896

别把num设成-1…因为有多个母串…

POJ 2778

题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。(仅含A,T,C,G四个字符)

解题思路:

AC自动机+矩阵快速幂

http://blog.csdn.net/morgan_xww/article/details/7834801

这里涉及到用Trie图构造邻接矩阵…

于是补了一下Trie图的构建…

http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html

这里还有一个知识点:矩阵A^m所代表的意义就是从点与点之间走m步能够到达的方案总数。

http://blog.csdn.net/WT_cnyali/article/details/69803030

img

HDU 2243

题意:给定n个单词,求长度不大于m的字符串中所有含给定单词的字符串的个数 。

解题思路:

整体和上题相似,即所有情况再减去上题求的情况即可。

img

将运算过程中的变量和矩阵的元素定义为unsigned __int64,就能实现自动对2^64自动取MOD。注意输出是%I64u。

HDU 2457

题意:已知一个DNA串和一些病毒DNA序列,求出最少改变DNA串中多少个字符,能使得串中不包含任意一个病毒序列。

解题思路:Trie图+DP。
先构造Trie图,这里要注意如果fail指针指向危险子串的本身也危险,
if(temp->child[i]->fail->num==1)//注意:fail指针指向危险子串的本身也危险
temp->child[i]->num=1;
之后就是DP,f[i][j]表示匹配到原串第i个字符时,在AC自动机的j号节点时没有病毒串的最小花费。转移的时候有三种情况:1.转移出病毒串,这个时候直接continue。2.转移与原串相符,这个时候直接将数值转移过去。3.转移与原串不符,这个时候转移数值之后还要+1,再在dp[len][i]中找到最小值。
   for(int i=0;i<=len;i++)
    for(int j=0;j<sum;j++)
        dp[i][j]=INF;
    dp[0][0]=0;
    for(int i=1;i<=len;i++)
    for(int j=0;j<sum;j++)
    if(dp[i-1][j]<INF)//不是从病毒串转移的
    {
        for(int k=0;k<4;k++)
        {
            if(Trie[j].child[k]->num==0)//不是一个单词的结尾
            {
                p=Trie[j].child[k];
                //转移与原串相符,这个时候直接将数值转移过去。转移与原串不符,这个时候转移数值之后还要+1。
                dp[i][p->idd]=min(dp[i][p->idd],dp[i-1][j]+(bh(str[i-1])!=k));
            }
        }
    }
    int ans=INF;
    for(int i=0;i<sum;i++)
    {
        if(Trie[i].num==0&&dp[len][i]<ans)
            ans=dp[len][i];
    }
    if(ans==INF)ans=-1;

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

线段树专题 Previous
KMP&扩展KMP&Manacher专题 Next