首先我们要考虑给定一个串,如何将他划分,使得他有最多的禁忌串

我们只需要按里面出现的禁忌串们的出现的右端点排序然后贪心就可以啦

我们建出AC自动机,在AC自动机等价于走到一个包含禁忌串的节点就划分出一段

那么不妨设f(i,j)表示走了i步当前在AC自动机的j节点上

这样的DP方程跟BZOJ 1030是类似的

但是由于i可能会很大,但是j是很小的,又因为每一步的转移都是一样的

所以我们可以考虑矩阵乘法来优化DP

可是当我们用AC自动机构建了转移矩阵之后,我们会发现我们没办法算答案

我们只能算经过L步到达AC自动机某节点的概率

那么我们不妨新建节点表示答案,在每次出现禁忌串的时候在新建节点上贡献相应的期望

同时新建节点要将上次贡献得到的期望传递给下一次的转移

所以矩阵中n->n存在转移

值得一提的是:这个题目卡精度,我一开始写的double,结果WA了

去网上看了看题解之后默默的改成了long double,然后A了

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std; const int maxn=102;
int n,L,k,cnt;
bool vis[maxn];
char s[maxn];
int t[maxn][26];
int fail[maxn];
bool end[maxn];
struct Matrix{
long double a[maxn][maxn];
Matrix(){memset(a,0,sizeof(a));}
}A,ans;
queue<int>Q; void insert(){
scanf("%s",s+1);
int len=strlen(s+1),now=1;
for(int i=1;i<=len;++i){
int id=s[i]-'a';
if(!t[now][id])t[now][id]=++cnt;
now=t[now][id];
}end[now]=true;
}
void build_fail(){
Q.push(1);fail[1]=0;
while(!Q.empty()){
int u=Q.front();Q.pop();
end[u]|=end[fail[u]];
for(int i=0;i<k;++i){
int tmp=fail[u];
while(tmp&&!t[tmp][i])tmp=fail[tmp];
if(t[u][i]){
fail[t[u][i]]=tmp?t[tmp][i]:1;
Q.push(t[u][i]);
}else t[u][i]=tmp?t[tmp][i]:1;
}
}A.a[n][n]=1;return;
}
void build_Matrix(){
vis[1]=true;Q.push(1);
long double tmp=1.0/k;
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=0;i<k;++i){
if(!vis[t[u][i]]){
vis[t[u][i]]=true;
Q.push(t[u][i]);
}
if(end[t[u][i]]){
A.a[u][n]+=tmp;
A.a[u][1]+=tmp;
}else A.a[u][t[u][i]]+=tmp;
}
}return;
}
Matrix operator *(const Matrix &A,const Matrix &B){
Matrix C;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
for(int k=1;k<=n;++k){
C.a[i][j]=C.a[i][j]+A.a[i][k]*B.a[k][j];
}
}
}return C;
}
Matrix pow_mod(int p){
Matrix tmp;
for(int i=1;i<=n;++i)tmp.a[i][i]=1;
while(p){
if(p&1)tmp=tmp*A;
A=A*A;p>>=1;
}return tmp;
} int main(){
scanf("%d%d%d",&n,&L,&k);cnt=1;
for(int i=1;i<=n;++i)insert();
n=cnt+1;
build_fail();build_Matrix();
ans=pow_mod(L);
printf("%.7lf\n",(double)(ans.a[1][n]));
return 0;
}

  

BZOJ 2553 禁忌的更多相关文章

  1. bzoj 2553 [BeiJing2011]禁忌——AC自动机+概率DP+矩阵

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2553 看了题解才会…… 首先,给定一个串,最好的划分方式是按禁忌串出现的右端点排序,遇到能填 ...

  2. 【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp

    我一开始想的是倒着来,发现太屎,后来想到了一种神奇的方法——我们带着一个既有期望又有概率的矩阵,偶数(2*id)代表期望,奇数(2*id+1)代表概率,初始答案矩阵一列,1的位置为1(起点为0),工具 ...

  3. bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2553 题解: 利用AC自动机的dp求出所有的转移 然后将所有的转移储存到矩阵中,进行矩阵 ...

  4. BZOJ - 2553 :禁忌(AC自动机+贪心+奇怪的矩阵)

    Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi恢复了读心的能力…… 如今,在John已经成为传说的时代, ...

  5. BZOJ 2553 AC自动机+矩阵快速幂 (神题)

    思路: 我们先对所有读进来的T建一个AC自动机 因为走到一个禁忌串就需要回到根 所以呢 搞出来所有的结束点 或一下 fail指针指向的那个点 然后我们就想转移 a[i][j]表示从i节点转移到j节点的 ...

  6. 省选前的th题

    沙茶博主终于整完了知识点并学完了早该在NOIP之前学的知识们 于是终于开始见题了,之前那个奇怪的题单的结果就是这个了 题目按沙茶博主的做题顺序排序 个人感觉(暂时)意义不大的已被自动忽略 洛谷 491 ...

  7. [BJOI2011]禁忌 --- AC自动机 + 矩阵优化 + 期望

    bzoj 2553 [BJOI2011]禁忌 题目描述: Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi ...

  8. 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂

    [题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...

  9. BZOJ2553: [BeiJing2011]禁忌

    2553: [BeiJing2011]禁忌 Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 203  Solved: ...

随机推荐

  1. .net设计模式之观察者模式

    摘要     在今天的设计模式系列中我给大家带来了观察者模式,首先我会以一个生动的故事引入观察者模式的应用的场景,然后描述这个场景中出现的问题,最后我们提出观察者模式的解决方案,并给出C#语言实现的代 ...

  2. 开放封闭原则(OCP)

    开放封闭原则 转:http://baike.baidu.com/view/2493421.htm转:http://dev.csdn.net/article/38/38826.shtm 开放封闭原则(O ...

  3. (转).NET技术+25台服务器怎样支撑世界第54大网站

    英文原文:StackOverflow Update: 560M Pageviews A Month, 25 Servers, And It's All About Performance StackO ...

  4. 第一节 Hibernate 基本配置

    1 新建maven工程 1)打开eclipse,依次点击File---->New---->Maven Project. 2)选择org.apache.maven.archetypes ma ...

  5. Traveller项目介绍

    Traveller,翻译为旅行家,是我用来实践最佳web技术的项目,主题是一个给旅行爱好者提供旅行信息的网站. 目标是组合现最流行的web技术,实现符合中国用户使用习惯的网站. 相关网址 Git:ht ...

  6. mac下安装redis

    安装php_redis.so 首先用git从https://github.com/nicolasff/phpredis下载源码.然后依次执行以下命令 sudo /Applications/XAMPP/ ...

  7. 图片延迟加载库Layzr

    <!DOCTYPE html> <html> <head> <title>Layzr Demo</title> <script src ...

  8. 关于hadoop2.4.2版本学习时遇到的问题

    问题一:namenode启动失败 描述:在初始化后hadoop后,发现datanode启动失败,namenode则可以正常启动,如果把用户换成root权限,再次启动时,则namenode和datano ...

  9. Python学习_算数运算函数

    记录以grades列表为例,分别定义输出.求和.平均值.方差和标准差函数,并输出相应的值 grades = [100, 100, 90, 40, 80, 100, 85, 70, 90, 65, 90 ...

  10. 如何将无线路由器作为交换机,将光猫(路由器A)分出来的一条网线接到自家另一台路由器B上,最大化利用网络资源

    从隔壁邻居只接了一条网线过来,由于无线网络的距离有限,不能覆盖到家里任何角落,然而,我又想家里一台台式电脑和无线设备都能够连接wifi进行上网。 摸索了一个上午,知道将家里的无线路由器B当作一个无线A ...