poj1625Censored!(AC自动机+dp)
第一次做这种题目,参考了下题解,相当于把树扯直了做DP,估计这一类题都是这个套路吧。
状态方程dp[i][next] = dp[i][next]+dp[i][j] ;dp[i][j]表示长度为i的第J个结点的时候满足题意的num,next为当前j点所能走到的下一个合法的结点。
需要用高精度,看到一些规范的高精度写法,觉得不错,有空整理下来。
不知道是不是我理解错了,按理说字符串病毒长度不应超过10.。但开到55依旧RE,开550AC。。。
- #include <iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<stdlib.h>
- #include<vector>
- #include<cmath>
- #include<queue>
- #include<set>
- using namespace std;
- #define N 110
- #define LL long long
- #define INF 0xfffffff
- const double eps = 1e-;
- const double pi = acos(-1.0);
- const double inf = ~0u>>;
- const int child_num = ;
- const int BASE = ;
- const int DIG = ;
- char s[N*],vir[];
- int id[];
- struct bignum
- {
- int a[],len;
- bignum()
- {
- memset(a,,sizeof(a));
- len = ;
- }
- bignum(int v)
- {
- memset(a,,sizeof(a));
- len = ;
- do
- {
- a[len++] = v%BASE;
- v/=BASE;
- }while(v);
- }
- /*bignum(const char s[])
- {
- memset(a,0,sizeof(a));
- int k = strlen(s);
- len = k/DIG;
- if(k%DIG) len++;
- int cnt = 0;
- for(int i = k-1; i >= 0 ; i-=DIG)
- {
- int t = 0;
- int kk = i-DIG+1;
- if(kk<0) kk =0;
- for(int j = kk ; j <= i ; j++)
- t = t*10+s[j]-'0';
- a[cnt++] = t;
- }
- }*/
- bignum operator + (const bignum &b)const
- {
- bignum res;
- res.len = max(len,b.len);
- int i;
- for(i = ; i < res.len ;i ++)
- res.a[i] = ;
- for(i = ; i < res.len ; i++)
- {
- res.a[i] += ((i<len)?a[i]:)+((i<b.len)?b.a[i]:);
- res.a[i+] += res.a[i]/BASE;
- res.a[i] = res.a[i]%BASE;
- }
- if(res.a[res.len]>) res.len++;
- return res;
- }
- void output()
- {
- printf("%d",a[len-]);
- for(int i = len- ; i >= ; i--)
- printf("%04d",a[i]);
- printf("\n");
- }
- }dp[][];
- class AC
- {
- private:
- int ch[N][child_num];
- int Q[N];
- int val[N];
- int fail[N];
- //int id[N];
- int sz;
- public :
- void init()
- {
- fail[] = ;
- //for(int i = 0 ;i < child_num-32 ; i++)
- //id[i+32] = i;
- }
- void reset()
- {
- memset(val,,sizeof(val));
- memset(fail,,sizeof(fail));
- memset(ch[],,sizeof(ch[]));
- sz = ;
- }
- void insert(char *a,int key)
- {
- int k = strlen(a),p = ;
- for(int i = ; i < k ;i++)
- {
- int d = id[a[i]];
- if(ch[p][d]==)
- {
- memset(ch[sz],,sizeof(ch[sz]));
- ch[p][d] = sz++;
- }
- p = ch[p][d];
- }
- val[p] = key;
- }
- void construct(int n)
- {
- int i,head=,tail = ;
- for(i = ; i < n ; i++)
- {
- if(ch[][i])
- {
- Q[tail++] = ch[][i];
- fail[ch[][i]] = ;
- }
- }
- while(head!=tail)
- {
- int u = Q[head++];
- val[u]|=val[fail[u]];
- for(i = ; i < n ; i++)
- {
- if(ch[u][i])
- {
- Q[tail++] = ch[u][i];
- fail[ch[u][i]] = ch[fail[u]][i];
- }
- else ch[u][i] = ch[fail[u]][i];
- }
- }
- }
- void work(int m,int n)
- {
- int i,j,g;
- for(i = ; i <= m ;i++)
- for(j = ;j <= sz; j++)
- dp[i][j] = bignum();
- dp[][] = bignum();
- for(i = ; i < m ;i++)
- {
- for(j = ; j < sz ;j++)
- for(g = ; g < n ; g++)
- if(!val[ch[j][g]])
- {
- dp[i+][ch[j][g]]=dp[i+][ch[j][g]]+dp[i][j];
- }
- }
- bignum ans = bignum();
- for(j = ;j < sz ; j++)
- ans=ans+dp[m][j];
- ans.output();
- }
- }ac;
- int main()
- {
- int n,m,i,p;
- ac.init();
- while(cin>>n>>m>>p)
- {
- cin>>s;
- for(i = ; i < n; i++)
- id[s[i]] = i;
- ac.reset();
- for(i = ;i <= p; i++)
- {
- scanf("%s",vir);
- ac.insert(vir,);
- }
- ac.construct(n);
- ac.work(m,n);
- }
- return ;
- }
poj1625Censored!(AC自动机+dp)的更多相关文章
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2296——Ring(AC自动机+DP)
题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...
- tyvj P1519 博彩游戏(AC自动机+DP滚动数组)
P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...
- bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...
随机推荐
- PHP检测移动设备类mobile detection使用实例
目前,一个网站有多个版本是很正常的,如PC版,3G版,移动版等等.根据不同的浏览设备我们需要定向到不同的版本中.不仅如此,我们有时候还需要根据不同的客户端加载不同的CSS,因此我们需要能够检测浏览设备 ...
- 接口测试从未如此简单 - Postman (Chrome插件)
接口测试从未如此简单 - Postman (Chrome插件) 一个非常有力的Http Client工具用来测试Web服务的, 我这里来介绍如何用它测试restful web service 注:转载 ...
- Android中<meta-data>的使用
[转] 原文 在AndroidManifest.xml中,<meta-data>元素可以作为子元素,被包含在<activity>.<application> .& ...
- [troubleshoot][daily][archlinux][pacman] pacman 与 pip 包文件冲突
今天滚系统,再次遭遇包冲突: (/) checking % error: failed to commit transaction (conflicting files) python2-reques ...
- JavaScript 字符 "转换
后台把一个Json类型的数据当成字符串返回到前台,但是到前台变成了下面的这个样子 "[{"name":"IE","y":72},{ ...
- css3超过指定宽度文字,显示省略号
text-overflow:ellipsis; overflow:hidden; white-space:nowrap; width:200px;
- C#异步:实现一个最简单的异步
异步就是方法异步执行, 这个好理解. 异步有啥用? 以前只是听说过, 也不想计较. 不过还是碰到了需要这个东西的时候. 比如: 定时执行, 如果不用异步方法,也不用定时器,只用Thread.Sleep ...
- pepperflash
sudo apt-get install pepperflashplugin-nonfree sudo update-pepperflashplugin-nonfree --install
- Spring 计划
3.0----------------------------------------------------- SCRUM 流程的步骤2: Spring 计划 1. 确保product backlo ...
- PHP---------PHP函数里面的static静态变量
工作一年了,一年里很少用到static这个关键词,不管是类里面还是方法里面基本都没怎么用过.平时看到类里面有这个都没什么好奇的,今天在函数里面看到了这个,就去百度了一下. <?phpfuncti ...