BZOJ 1444:[JSOI2009]有趣的游戏
BZOJ 1444:[JSOI2009]有趣的游戏
首先我们建出Trie图,然后高斯消元。
我们设\(f_i\)表示经过第\(i\)个点的期望次数:
\]
\(p_x(i)\)表示经过第\(x\)个点\(i\)次的概率。我们设表示一个单词的节点为关键节点,则所有关键节点只会经过一次,也就是说\(f_{关键}=p_{关键}(1)\),也就是我们要求的答案。
\]
特别地\(\displaystyle f_1=\sum_{y与1相连}rate_{y\Rightarrow 1}f_y+1\),因为初始点在\(1\)。
\(rate_{y\Rightarrow x}\)就是能从\(y\)走到\(x\)的字母的出现概率。
根据这些等式列方程,再高斯消元就行了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 12
#define eps 1e-7
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int n,l,m;
double rate[26];
double w[N*N][N*N];
char str[N];
namespace AC_automation {
int cnt=1;
int id[N];
struct trie {
int ch[26];
int w,fail;
}tr[N*N];
void Insert(char *s,int No) {
int len=strlen(s+1),now=1;
for(int i=1;i<=len;i++) {
int j=s[i]-'A';
if(!tr[now].ch[j]) tr[now].ch[j]=++cnt;
now=tr[now].ch[j];
}
id[No]=now;
tr[now].w=1;
}
queue<int>q;
void build_fail() {
q.push(1);
while(!q.empty()) {
int v=q.front();
q.pop();
for(int i=0;i<26;i++) {
if(!tr[v].ch[i]) continue ;
int sn=tr[v].ch[i],f=tr[v].fail;
while(f&&!tr[f].ch[i]) f=tr[f].fail;
if(!f) tr[sn].fail=1;
else tr[sn].fail=tr[f].ch[i];
q.push(sn);
}
}
}
int find_sn(int now,int j) {
while(now&&!tr[now].ch[j]) now=tr[now].fail;
return now?tr[now].ch[j]:1;
}
void build_matrix() {
for(int i=1;i<=cnt;i++) {
w[i][i]=-1;
if(tr[i].w) continue ;
else {
for(int j=0;j<m;j++) {
int sn=find_sn(i,j);
w[sn][i]+=rate[j];
}
}
}
w[1][cnt+1]=-1;
}
}
int sum;
double ans[N*N];
void Gauss(int n) {
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
if(fabs(w[i][i])<fabs(w[j][i])) swap(w[i],w[j]);
if(fabs(w[i][i])<eps) continue ;
for(int j=i+1;j<=n;j++) {
double tem=w[j][i]/w[i][i];
for(int k=i;k<=n+1;k++) w[j][k]-=tem*w[i][k];
}
}
}
for(int i=n;i>=1;i--) {
if(fabs(w[i][i])<eps) {ans[i]=0;continue ;}
for(int j=i+1;j<=n;j++) w[i][n+1]-=w[i][j]*ans[j];
ans[i]=w[i][n+1]/w[i][i];
}
}
int main() {
n=Get(),l=Get(),m=Get();
double a,b;
for(int i=0;i<m;i++) {
a=Get(),b=Get();
rate[i]=a/b;
}
for(int i=1;i<=n;i++) {
scanf("%s",str+1);
AC_automation::Insert(str,i);
}
AC_automation::build_fail();
AC_automation::build_matrix();
sum=AC_automation::cnt;
Gauss(sum);
for(int i=1;i<=n;i++) {
double a=ans[AC_automation::id[i]];
if(fabs(a)>0.005) cout<<fixed<<setprecision(2)<<a<<"\n";
else cout<<"0.00"<<"\n";
}
return 0;
}
BZOJ 1444:[JSOI2009]有趣的游戏的更多相关文章
- BZOJ:4820: [Sdoi2017]硬币游戏&&BZOJ:1444: [Jsoi2009]有趣的游戏(高斯消元求概率)
1444: [Jsoi2009]有趣的游戏 4820: [Sdoi2017]硬币游戏 这两道题都是关于不断随机生成字符后求出现给定字符串的概率的问题. 第一题数据范围较小,将串建成AC自动机以后,以A ...
- BZOJ 1444: [Jsoi2009]有趣的游戏 [AC自动机 高斯消元]
1444: [Jsoi2009]有趣的游戏 题意:每种字母出现概率\(p_i\),有一些长度len的字符串,求他们出现的概率 套路DP的话,\(f[i][j]\) i个字符走到节点j的概率,建出转移矩 ...
- BZOJ 1444 [Jsoi2009]有趣的游戏 (AC自动机 + 概率DP + Gauss)
1444: [Jsoi2009]有趣的游戏 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1382 Solved: 498[Submit][Statu ...
- ●BZOJ 1444 [Jsoi2009]有趣的游戏
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1444题解.1: 概率dp,矩阵乘法,快速幂. 对所有串建立AC自动机, 那么如果在trie树 ...
- bzoj 1444: [Jsoi2009]有趣的游戏【AC自动机+dp+高斯消元】
https://blog.sengxian.com/solutions/bzoj-1444 orz 一直是我想错了,建出AC自动机之后,实际上这个定义是设f[i]为经过i节点的 * 期望次数 * ,因 ...
- BZOJ 1444 [JSOI2009]有趣的游戏 (AC自动机、概率与期望DP、矩阵乘法)
诶这题洛谷居然没有??? 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1444 题解: 我见到主要有三种做法. 一是矩阵乘法.设\(d ...
- BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)
题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...
- BZOJ 1444: [Jsoi2009]有趣的游戏 AC自动机+概率与期望+矩阵乘法
这道题还比较友好~首先,构建出来 $AC$ 自动机,那么我们要求的就是从 $0$ 号点走无限次走到一个终止节点的概率. 考虑构建转移矩阵 $M,$ $M_{i,j}$ 表示节点 $i$ 转移到节点 $ ...
- 1444: [Jsoi2009]有趣的游戏
1444: [Jsoi2009]有趣的游戏 链接 分析: 如果一个点回到0号点,那么会使0号点的概率增加,而0号点的概率本来是1,不能增加,所以这题用期望做. 设$x_i$表示经过i的期望次数,然后初 ...
随机推荐
- 猪圈密码 摩斯密码 QWE加密 栅栏加密 当铺密码
1.猪圈密码 猪圈密码:对应下图就是HORSE 2.摩斯密码 在线摩斯密码翻译器:http://www.mathsking.net/morse.htm 3.QWE加密 键盘按ABC的顺序排列得到对应的 ...
- python 输出颜色与样式的方法
上次遇到这个问题就想写下来,其实当时我也不怎么会,老师说这个东西不需要理解,只需要死记硬背,写的多了就记住了,所以今天搜集了几篇文章,加上自己的理解,写下了这篇python 输出颜色的样式与方法的文章 ...
- VirtualBox安装CentOS7
一:.下载CentOS7的镜像 下载地址:https://www.centos.org/download/ 进入后有三个版本可以选择: 1.DVD ISO 标准安装版,一般下载这个就可以了(推荐)本 ...
- JAVA对Excel的导入导出
今天需要对比2个excel表的内容找出相同:由于要学的还很多上手很慢所以在这做个分享希望对初学的有帮助: 先是pom的配置: <dependency> <groupId>org ...
- linux shell脚本之-变量极速入门与进阶(2)
1,$$:显示当前的进程id号 ghostwu@dev:~/linux/shell/how_to_use_var$ cat show_pid.sh #!/bin/bash echo $$ ghostw ...
- windows使用笔记-google-chrome下载地址
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! google-chrome下载地址:https://www.google.cn/intl/zh-CN/chrome/
- 原生js 对象深拷贝
经常需要copy一个对象,又怕拷贝有问题,那下面这段就很方便啦,不用担心copy只是一个引用了. /** @ values 需要copy的变量 */ function deepClone(values ...
- 前端打包文件在 nginx 上 403 的解决办法
遇到的问题表现出来就是如题所述,因此作为题目. 我们知道,前端有很多方便的构建和打包工具,如 webpack 等,通常我们会把前端文件打包到dist目录下,部署到服务器上,如 nginx 等. 这次遇 ...
- element-ui中table表头表格错误问题解决
我用的是element-ui v1.4.3 在iframe关闭和切换导航会引起有table的表格错位,解决办法: handleAdminNavTab: function(tab) { var admi ...
- python自动化开发-8
进程与线程 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程. 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位. ...