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

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

我们建出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. Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

    在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...

  2. ubuntu后台配置无线网络

    一.静态配置: 1.编辑 /etc/network/interfaces: auto loiface lo inet loopback auto wlan0iface wlan0 inet stati ...

  3. mysql配置优化测试

    http://bjlfp.blog.163.com/blog/static/77368461201211695924524/ 感觉真不错啊.观察几天看看

  4. 将C# dataTable 做为参数传入到存储过程

    1.list转换为DataTable(如果有需要) public static DataTable ListToDataTable<T>(List<T> entitys) { ...

  5. JS自定义属性的设置与获取

    以前感觉用JQuery来设置自定义属性很方便,现在没有用JQuery,要用原生的JavaScript来操作自定义属性. Jquery操作自定义属性的方法,很简洁: $("#test" ...

  6. Android源代码编译——下载

    下了好久的源代码,真真是慢哈.真希望国内有公司能够把镜像开放出来. 不多说,首先是系统环境,我的系统是Ubuntu 64位系统(14.04), 版本应该没什么. 需要的库 Git: 没话说必须, su ...

  7. YII框架源码分析(百度PHP大牛创作-原版-无广告无水印)

           YII 框架源码分析    百度联盟事业部——黄银锋 目 录 1. 引言 3 1.1.Yii 简介 3 1.2.本文内容与结构 3 2.组件化与模块化 4 2.1.框架加载和运行流程 4 ...

  8. python del函数

    del用于list列表及字典操作,删除一个或者连续几个元素也可以删除字典指定的key   示例程序如下: >>> a = [-1, 3, 'aa', 85] # 定义一个list&g ...

  9. Python在Windows下开发环境配置汇总

    最近比较关注学习Python方面的资料和课程,由于Python本身基本都是在Linux下开发,本人windows用习惯了初用Linux各种别扭啊. 下面将我在配置Windows环境下的禁言写出来,与大 ...

  10. Can’t create handler inside thread that has not called Looper.prepare()

    1)在Android 2.3以前,为防止ANR(Application Not Responding),Google是不赞成将网络连接等一系列耗时操作直接放到应用主线程进行的,推荐将这类操作放在子线程 ...