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的期望次数,然后初 ...
随机推荐
- VUE + ElementUI 从搭建到运行
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 前言:本文简洁的描述VUE + ElementUI 从搭建到运行,可以根据本文先搭建出可运行的项目,然后再详细回顾每个步骤所做的事: ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- Nginx反代Mogilefs分布式储存示例
一.分布式存储系统简介 随着信息技术不断的发展,给我们带来便利的同时,不断增加的数据量级.信息之间的连接关联越来越复杂.数据访问的并发量日益增加对I/O的要求越来越高.数据类型越来越复杂等难题也成为信 ...
- 动态规划法(八)最大子数组问题(maximum subarray problem)
问题简介 本文将介绍计算机算法中的经典问题--最大子数组问题(maximum subarray problem).所谓的最大子数组问题,指的是:给定一个数组A,寻找A的和最大的非空连续子数组.比如 ...
- 140 - The 12th Zhejiang Provincial Collegiate Programming Contest(第三部分)
Earthstone Keeper Time Limit: 4 Seconds Memory Limit: 65536 KB Earthstone Keeper is a famous ro ...
- kafka安装与简单使用
一.kafka安装 安装是非常简单的,现在推荐安装0.8的版本,这个版本是非常稳定的,而且公司里面也多用此版本. 简单的安装: 这个是我使用的版本,kafka_2.11-0.8.2.2.tgz 直接t ...
- js 绘制数学函数
<!-- <!doctype html> --> <html lang="en"> <head> <meta charset= ...
- pygame编程之font模块
方法一:pygame.font.Font(file, size=-1) 参数file:采用字体文件的路径,如果file参数设置为None则默认采用系统自带字体,如果自带字体文件无法打开就会报错: 参数 ...
- putty之pscp上传文件
控制台下打开pscp可执行文件 命令 >pscp -i 证书名 -r 要上传的文件 root@服务器路径:/opt
- java中多线程详解-synchronized
一.介绍 当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线 ...