链接

第一次做这种题目,参考了下题解,相当于把树扯直了做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)的更多相关文章

  1. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  2. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  3. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

  4. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

  5. hdu 2457(ac自动机+dp)

    题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...

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

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...

  8. tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

    P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...

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

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...

随机推荐

  1. Android实现推送方式解决方案

    当我们开发需要和服务器交互的应用程序时,基本上都需要获取服务器端的数据,比如<地震应急通>就需要及时获取服务器上最新的地震信息. 要获取服务器上不定时更新的信息,一般来说有两种方法: 第一 ...

  2. 解决pip国外安装源慢的问题

    用默认的pip安装源pypi.python.org由于在国外经常会出现超时的问题,而且安装速度极其的慢,如下图中的超时问题=>

  3. 使用所见即所得文本编辑器编辑文本存入数据库后通过ajax获取服务器json_encode的数据到前台,文本内容上边的html标签不解析

    使用所见即所得文本编辑器编辑文本存入数据库后通过ajax获取服务器json_encode的数据到前台,文本内容上边的html标签不解析 因为我在前台使用了jquery的text()方法,而不是html ...

  4. Swift 懒加载(lazy) 和 Objective-C 懒加载的区别

    在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间,比如iOS开发中的最常用控件UITableView,实现数据源方法的时候,通常我们都会这样写 Objective-C - ( ...

  5. 关于scrollWidth,clientWidth,offsetWidth

    scrollWidth:对象的实际内容的宽度,不包含边线(border)的宽度,会随对象的内容可视区后而变大. scrollHeight:对象的实际内容的高度,不包含边线(border)的宽度,会随对 ...

  6. 捕获Insert触发器失败记录

    1.背景 环境:发布服务器A Windows2008+SQL2008,分发服务器B Windows2008+SQL2008,订阅服务器C Windows2008+SQL2012发布服务器A上的用户信息 ...

  7. windows2003服务器mysql每天定时备份

    1.php利用mysqldump备份数据库,代码如下: <?php /** * 数据库备份 */ $sqlname = $argv[1]; //接受bat或cmd传过来的第一个参数 要备份的数据 ...

  8. STL之容器(1)

    STL容器类的模板 容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和 ...

  9. java栈与堆

    java基本类型: 变量存放在栈区 java引用类型: 变量名存放在栈区,变量内容存放在堆区. 实例一: int a = 6; int b = 9; swap(int x, int y) { int ...

  10. 关于system函数的安全性漏洞

    当以一个普通用户去执行  设置-用户ID 为root的程序时,如果再次用了system函数时,被system函数所执行的那个程序具有 有效-用户ID 为root的风险(虽然真实用户还是普通用户),这也 ...