链接

第一次做这种题目,参考了下题解,相当于把树扯直了做DP,估计这一类题都是这个套路吧。

状态方程dp[i][next] = dp[i][next]+dp[i][j] ;dp[i][j]表示长度为i的第J个结点的时候满足题意的num,next为当前j点所能走到的下一个合法的结点。

需要用高精度,看到一些规范的高精度写法,觉得不错,有空整理下来。

不知道是不是我理解错了,按理说字符串病毒长度不应超过10.。但开到55依旧RE,开550AC。。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 110
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 const int child_num = 110;
 18 const int BASE = 10000;
 19 const int DIG = 4;
 20 char s[N*100],vir[550];
 21 int id[2024];
 22 struct bignum
 23 {
 24      int a[110],len;
 25      bignum()
 26      {
 27          memset(a,0,sizeof(a));
 28          len = 1;
 29      }
 30      bignum(int v)
 31      {
 32          memset(a,0,sizeof(a));
 33          len = 0;
 34          do
 35          {
 36              a[len++] = v%BASE;
 37              v/=BASE;
 38          }while(v);
 39      }
 40      /*bignum(const char s[])
 41      {
 42          memset(a,0,sizeof(a));
 43          int k = strlen(s);
 44          len = k/DIG;
 45          if(k%DIG) len++;
 46          int cnt = 0;
 47          for(int i = k-1;  i >= 0 ; i-=DIG)
 48          {
 49              int t = 0;
 50              int kk = i-DIG+1;
 51              if(kk<0) kk =0;
 52              for(int j = kk ; j <= i ; j++)
 53              t = t*10+s[j]-'0';
 54              a[cnt++] = t;
 55          }
 56      }*/
 57      bignum operator + (const bignum &b)const
 58      {
 59          bignum res;
 60          res.len = max(len,b.len);
 61          int i;
 62          for(i = 0 ; i < res.len ;i ++)
 63          res.a[i] = 0;
 64          for(i = 0 ; i < res.len ; i++)
 65          {
 66              res.a[i] += ((i<len)?a[i]:0)+((i<b.len)?b.a[i]:0);
 67              res.a[i+1] += res.a[i]/BASE;
 68              res.a[i] = res.a[i]%BASE;
 69          }
 70          if(res.a[res.len]>0) res.len++;
 71          return res;
 72      }
 73      void output()
 74      {
 75          printf("%d",a[len-1]);
 76          for(int i = len-2 ; i >=0 ; i--)
 77          printf("%04d",a[i]);
 78          printf("\n");
 79      }
 80 }dp[110][110];
 81 class AC
 82 {
 83     private:
 84     int ch[N][child_num];
 85     int Q[N];
 86     int val[N];
 87     int fail[N];
 88     //int id[N];
 89     int sz;
 90     public :
 91     void init()
 92     {
 93         fail[0] = 0;
 94         //for(int i = 0 ;i < child_num-32 ; i++)
 95         //id[i+32] = i;
 96     }
 97     void reset()
 98     {
 99         memset(val,0,sizeof(val));
100         memset(fail,0,sizeof(fail));
101         memset(ch[0],0,sizeof(ch[0]));
102         sz = 1;
103     }
104     void insert(char *a,int key)
105     {
106         int k = strlen(a),p = 0;
107         for(int i = 0 ; i < k ;i++)
108         {
109             int d = id[a[i]];
110             if(ch[p][d]==0)
111             {
112                 memset(ch[sz],0,sizeof(ch[sz]));
113                 ch[p][d] = sz++;
114             }
115             p = ch[p][d];
116         }
117         val[p] = key;
118     }
119     void construct(int n)
120     {
121         int i,head=0,tail = 0;
122         for(i = 0; i < n ; i++)
123         {
124             if(ch[0][i])
125             {
126                 Q[tail++] = ch[0][i];
127                 fail[ch[0][i]] = 0;
128             }
129         }
130         while(head!=tail)
131         {
132             int u = Q[head++];
133             val[u]|=val[fail[u]];
134             for(i = 0 ; i < n ; i++)
135             {
136                 if(ch[u][i])
137                 {
138                     Q[tail++] = ch[u][i];
139                     fail[ch[u][i]] = ch[fail[u]][i];
140                 }
141                 else ch[u][i] = ch[fail[u]][i];
142             }
143         }
144     }
145     void work(int m,int n)
146     {
147         int i,j,g;
148         for(i = 1; i <= m ;i++)
149             for(j = 0 ;j <= sz; j++)
150             dp[i][j] = bignum(0);
151         dp[0][0] = bignum(1);
152         for(i = 0 ; i < m ;i++)
153         {
154             for(j = 0 ; j < sz ;j++)
155             for(g = 0 ; g < n ; g++)
156             if(!val[ch[j][g]])
157             {
158                 dp[i+1][ch[j][g]]=dp[i+1][ch[j][g]]+dp[i][j];
159             }
160         }
161         bignum ans = bignum(0);
162         for(j = 0 ;j < sz ; j++)
163         ans=ans+dp[m][j];
164         ans.output();
165     }
166 }ac;
167 int main()
168 {
169     int n,m,i,p;
170     ac.init();
171     while(cin>>n>>m>>p)
172     {
173         cin>>s;
174         for(i = 0 ; i < n; i++)
175         id[s[i]] = i;
176         ac.reset();
177         for(i = 1;i <= p; i++)
178         {
179             scanf("%s",vir);
180             ac.insert(vir,1);
181         }
182         ac.construct(n);
183         ac.work(m,n);
184     }
185     return 0;
186 }

View Code

转载于:https://www.cnblogs.com/shangyu/p/3730815.html

poj1625Censored!(AC自动机+dp)相关推荐

  1. uvalive4842(AC自动机+DP)

    题意: 给出猴子打字时打某个字母的概率,猴子最多可以敲键盘m次,问得到的长度是m的单词包含模式串的概率. 思路: AC自动机+dp. 首先,我们用模式串构造一个AC自动机,用dp[i]][j]表示当前 ...

  2. HDU 2296 Ring AC自动机 + DP

    题意:给你n个模式串,每个模式串有一个得分,让你构造出一个长度为N之内且分数最高的文本串;输出字典序列最小的. 解题思路:  AC自动机 + DP , 不过要输出字典序列最小,多开一个 一个三维字符串 ...

  3. bzoj 1030: [JSOI2007]文本生成器(AC自动机+DP)

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 5187  Solved: 2136 [Submit][St ...

  4. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  5. POJ 3691 DNA repair AC自动机 + DP

    题意:给你只包含'A','G','T','C'四个字母的n个模板串和1个文本串,问你文本串改变多少个字符就可以使得文本串中没有一个模板串 解题思路: 我们可以知道  dp[i][j] 为文本串到 第i ...

  6. 【HDU 4511】小明系列故事——女友的考验(AC自动机+DP)

    Problem Description 终于放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则: ...

  7. CDOJ1633 Video Game Combos [AC自动机+dp]

    题目地址:http://acm.uestc.edu.cn/problem.php?pid=1633 AC自动机+BFS AC自动机,参见:http://www.cnblogs.com/luna-lov ...

  8. [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)

    题目传送门 题目描述: JSOI交给队员ZYX一个任务,编制一个称之为"文本生成器"的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机 ...

  9. BZOJ3075[USACO 2013 Mar Gold 3.Necklace]——AC自动机+DP

    题目描述 给你一个长度为n的字符串A,再给你一个长度为m的字符串B,求至少在A中删去多少个字符才能使得B不是A的子串.注:该题只读入A和B,不读入长度,先读入A,再读入B.数据保证A和B中只含小写字母 ...

最新文章

  1. 收藏!中国卫星互联网产业发展白皮书
  2. Xml,XPath,XSLTxue 学习方法
  3. 执行 pip3 install selenium 时出现 fail to create process
  4. android arm
  5. 【转】Ubuntu中SVN客户端安装+使用
  6. Ubuntu14.04下安装Chrome出现“未安装软件包 libappindicator1”问题的解决办法
  7. 鸿蒙对抗谷歌,华为下定决心对抗谷歌,打出第一张王牌,鸿蒙系统更进一步
  8. C语言例题——密码校验
  9. keyshot可以打开mtl文件吗_KeyShot:bip文件是什么?bip文件用什么打开?
  10. svn图标不显示的问题
  11. 安川ga700变频器故障码集_安川变频器故障代码和报警参数大全
  12. win7怎么把计算机图标下的箭头掉,win7系统桌面图标小箭头去掉的操作方法
  13. MySQL8.0中消失又回来的磁盘临时表
  14. 前端canvas画海报
  15. initial-scale
  16. gdb @entry= 是什么意思
  17. error C2899: 不能在模板声明之外使用类型名称
  18. 1998-2014年工企污染数据库
  19. xutils找id空指针_xutils3上传图片
  20. lda主题模型python_LDA主题模型及python实现

热门文章

  1. mysql常见增量恢复方式_MySQL 全备份与增量备份 全恢复与增量恢复
  2. autodesk许可证服务器,Autodesk软件工作流介绍(十)——配置网络许可服务器的步骤...
  3. java语言环境变量_JAVA语言环境变量的设置教程
  4. python期末考试及答案广东卷_python数据分析答案试题题目及答案,期末考试题库,章节测验答案...
  5. 王建春计算机应用基础,计算机应用基础(本)教学指南.pdf
  6. mysql8.0.12最小化安装_简述MySql8.0编译安装过程
  7. android类名方法名不混淆,android – 如何告诉Proguard混淆类名
  8. 单片机红绿灯电路灯有几种_LED路灯电源防雷与设计方案
  9. 力扣(LeetCode)刷题,简单+中等题(第33期)
  10. OpenCV(24)角点检测3 -- ORB