题目链接:点击进入
其实看起来是完全可以用矩阵做的,但是因为用到了大数的,导致内存开不下,所以用dp写了。其实dp的过程依旧就是在我们用禁止出现单词构建的trie上走m步的过程。我们定义dp[i][j]表示走过i步以后到达节点j的方案数,则状态转移应该是dp[i][j]=sum(dp[i-1][k]),其中k表示可以走到j的节点,并且不能是病毒节点。但是其实这样代码就不是那么好写了,其实我们可以用节点j主动的去更新它的子节点k,这样转移方程就成了dp[i][next[j][k]]+=dp[i-1][j]。要求next[j][k]不能使病毒节点。总而言之,AC自动机上的dp就是要利用我们建立的trie树以及上面的转移方式进行状态转移。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<map>
using namespace std;///大数模版
struct BigInteger{int A[25];enum{MOD = 10000};BigInteger(){memset(A, 0, sizeof(A)); A[0]=1;}void set(int x){memset(A, 0, sizeof(A)); A[0]=1; A[1]=x;}void print(){printf("%d", A[A[0]]);for (int i=A[0]-1; i>0; i--){if (A[i]==0){printf("0000"); continue;}for (int k=10; k*A[i]<MOD; k*=10) printf("0");printf("%d", A[i]);}printf("\n");}int& operator [] (int p) {return A[p];}const int& operator [] (int p) const {return A[p];}BigInteger operator + (const BigInteger& B){BigInteger C;C[0]=max(A[0], B[0]);for (int i=1; i<=C[0]; i++)C[i]+=A[i]+B[i], C[i+1]+=C[i]/MOD, C[i]%=MOD;if (C[C[0]+1] > 0) C[0]++;return C;}BigInteger operator * (const BigInteger& B){BigInteger C;C[0]=A[0]+B[0];for (int i=1; i<=A[0]; i++)for (int j=1; j<=B[0]; j++){C[i+j-1]+=A[i]*B[j], C[i+j]+=C[i+j-1]/MOD, C[i+j-1]%=MOD;}if (C[C[0]] == 0) C[0]--;return C;}
}One;const int maxn=10*10+5;
char alph[maxn];
map<char,int>h;int getIndex(char ch)
{return h[ch];
}struct Trie
{int next[maxn][maxn/2],fail[maxn],flag[maxn];int root,L,len;int newnode(){memset(next[L],-1,sizeof(next[L]));flag[L++];return L-1;}void init(){L=0;root=newnode();}void insert(char buf[]){int len1=strlen(buf);int now=root;for(int i=0;i<len1;i++){int index=getIndex(buf[i]);if(next[now][index]==-1)next[now][index]=newnode();now=next[now][index];}flag[now]=1;}void build(){queue<int>Q;fail[root]=root;for(int i=0;i<len;i++){if(next[root][i]==-1)next[root][i]=root;else{fail[next[root][i]]=root;Q.push(next[root][i]);}}while(!Q.empty()){int now=Q.front();if(flag[fail[now]])flag[now]++;Q.pop();for(int i=0;i<len;i++){if(next[now][i]==-1)next[now][i]=next[fail[now]][i];else{fail[next[now][i]]=next[fail[now]][i];//flag[next[now][i]]|=flag[next[fail[now]][i]];Q.push(next[now][i]);}}}}
};Trie ac;
char str[maxn];BigInteger dp[maxn][maxn];int main()
{int n,m,p;///freopen("in.txt","r",stdin);One.set(1);while(scanf("%d%d%d",&n,&m,&p)!=EOF){h.clear();scanf("%s",alph);for(int i=0;i<strlen(alph);i++)h[alph[i]]=i;ac.init();ac.len=strlen(alph);for(int i=0;i<p;i++){scanf("%s",str);ac.insert(str);}ac.build();for(int i=0;i<=m;i++)for(int j=0;j<ac.L;j++)dp[i][j].set(0);dp[0][0].set(1);for(int i=1;i<=m;i++)for(int j=0;j<ac.L;j++)for(int k=0;k<n;k++){if(ac.flag[ac.next[j][k]]) continue;dp[i][ac.next[j][k]]=dp[i][ac.next[j][k]]+dp[i-1][j];}BigInteger ans;ans.set(0);for(int i=0;i<ac.L;i++)ans=ans+dp[m][i];ans.print();}return 0;
}

poj--1625Censored!+AC自动机上的dp+大数相关推荐

  1. 【BZOJ1030】[JSOI2007] 文本生成器(AC自动机上跑DP)

    点此看题面 大致题意: 给你\(N\)个字符串(只含大写字母),要你求出有多少个由\(M\)个大写字母构成的字符串含有这\(N\)个字符串中的至少一个. \(AC\)自动机 看到题目,应该比较容易想到 ...

  2. POJ 1625 Censored!(AC自动机-指针版+DP+大数)题解

    题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...

  3. BZOJ4861 魔法咒语 【AC自动机】【DP】【矩阵快速幂】

    题意: 用n个基本词汇拼出长度为L的字符串,每个基本词汇可以用0次,1次或多次,要求拼出的字符串不能出现m个禁忌词汇中的任何一个,求方案数 mod 1e9+7 60% :1<=N,M<=5 ...

  4. 【HDU2825】Wireless Password,AC自动机+状态压缩DP

    传送门 写在前面:依旧有毒的HDU,读题半天看不懂啊,感觉自动机的精通遥遥无期啊! 思路: 题意--给定m个给定的串(可能相同),要求组建一个给定长度为n的新串,要求新串中至少包含k个给定的串(序号重 ...

  5. hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)

    考研路茫茫--单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. HDU - 2825 Wireless Password (AC自动机 + 状压dp)

    题目链接 题意 求至少包含KKK个给定字符串长度为NNN的字符串 思路 把所有可能的字符串建AC自动机,遍历所有节点dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示以节点jjj ...

  7. P4045-[JSOI2009]密码【AC自动机,状压dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P4045 题目大意 给nnn个字符串,求有多少个长度为lll的字符串包含所有给出的字符串 解题思路 因为nnn很小, ...

  8. 关于【AC自动姬】的学习

    突然发现自己还不会AC自动姬,就去学了一下下... 自动姬de用途: 给你n个模式串,1个文本串,求出有多少模式串在文本串中出现过.(详见洛谷P3808) 大体思路: 我先前貌似介绍过一种叫做KMP的 ...

  9. Censored! POJ - 1625 AC自动机+大数DP

    题意: 给出一n种字符的字典,有p个禁用的单词, 问能组成多少个不同的长度为m的合法字符串.(m<=50) 题解: 是不是个我们之前做的题目非常非常像,题意都一样. 直接将上次写的AC自动机+矩 ...

最新文章

  1. cesium 设置时间_Cesium之地形制作与合并
  2. MySql 中 case when then else end 的用法
  3. 项目中的加减法--《最后期限》读书笔记(1)
  4. 智能营销增益模型(Uplift Modeling)的原理与实践
  5. 使用C#和MSMQ开发消息处理程序
  6. linux嵌入式物联网_嵌入式Linux如何加速物联网发展
  7. markdown转换html源码,利用Nodejs+Express将Markdown转换为HTML(附源码)
  8. 荣获2009年“微软最有影响力开发者”称号
  9. OpenCV-怀旧色滤镜
  10. 开课吧学python靠谱吗-如何选择python培训机构?开课吧python培训怎么样?
  11. 随机数相加等于固定值_excel随机函数出来的数相加等于一个想要的固定值
  12. case 逻辑java,java – 了解CaseInsensitiveComparator中的逻辑
  13. 如何将开源项目部分代码作为private放在github上?
  14. mathematica 如何在数组中等间隔插入元素
  15. 一起谈.NET技术,疯狂的想法——基于.NET的软件超市平台构想与5年实现之路
  16. OpenCV 人脸识别DNN face detector文件下载(opencv_face_detector.pbtxt;opencv_face_detector_uint8.pb;。。。。)
  17. B7 HTML5期末大作业:海贼王影视网站设计——仿京东-海贼王(1页) HTML+CSS+JavaScript 学生DW网页设计作业成品 wweb前端期末大作业 网页设计实例 企业网站制作
  18. 玩转华为ENSP模拟器系列 | 配置L3VdPdNd迭代SR-BE隧道示例
  19. 如何像伟大的企业家一样写作
  20. 在职研究生计算机专业院校,计算机专业在职研究生报名有哪些院校可以选择?...

热门文章

  1. 要学的东西太多了怎么办
  2. 看不见的竞争 之 把握意见领袖
  3. 关于大淘客CMS免费二次开发分享的曝光
  4. 实时数据库 - 笔记
  5. 手把手带你了解Spark作业“体检报告” --Spark UI
  6. ORAN C平面 Section Extension 5
  7. 20165218 我期望的师生关系
  8. 不登高山,不知天之高也;不临深溪,不知地之厚也
  9. New Year Snowmen((贪心)map+优先队列)
  10. Java 恋爱纪念日(日期问题)