https://blog.sengxian.com/solutions/bzoj-1444 orz

一直是我想错了,建出AC自动机之后,实际上这个定义是设f[i]为经过i节点的 * 期望次数 * ,因为单词末尾节点走到意味着游戏结束,所以经过单词末尾节点的概率就是经过单词末尾节点的期望次数。为什么是期望呢,因为概率的上限是1,不能随便转移

这样定义状态之后,得到dp转移为

\[f[i]=\sum_{pr节点可以通过字符c转移到i节点}p[c]*f[pr]
\]

因为是期望,所以root节点右边要加1

然后移项做高斯消元即可

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
const int N=105;
int n,l,m,c[N][15],tot=1,fa[N],va[N],fl,id[N];
double p[N],a[N][N],d[N];
char s[N];
void gaosi(int n)
{
for(int i=1;i<=n;i++)
{
int nw=i;
for(int j=i+1;j<=n;j++)
if(fabs(a[nw][i])<fabs(a[j][i]))
nw=j;
for(int j=i;j<=n+1;j++)
swap(a[nw][j],a[i][j]);
for(int j=i+1;j<=n+1;j++)
a[i][j]/=a[i][i];
a[i][i]=1;
for(int j=i+1;j<=n;j++)
{
for(int k=i+1;k<=n+1;k++)
a[j][k]-=a[j][i]*a[i][k];
a[j][i]=0;
}
}
for(int i=n-1;i>=1;i--)
for(int j=i+1;j<=n;j++)
a[i][n+1]-=a[j][n+1]*a[i][j];
}
int main()
{
scanf("%d%d%d",&n,&l,&m);
for(int i=0,x,y;i<m;i++)
{
scanf("%d%d",&x,&y);
p[i]=(double)x/(double)y;
}
for(int ca=1;ca<=n;ca++)
{
scanf("%s",s+1);
int nw=1,f=0;
for(int i=1;i<=strlen(s+1);i++)
{
if(p[s[i]-'A']<1e-8)
f=1;
if(!c[nw][s[i]-'A'])
c[nw][s[i]-'A']=++tot;
nw=c[nw][s[i]-'A'];
}
va[nw]=1;
id[ca]=tot;//cerr<<id[ca]<<endl;
fl+=f;
}
if(fl==n)
{
for(int i=1;i<=n;i++)
puts("0.00");
return 0;
}
queue<int>q;
for(int i=0;i<m;i++)
if(c[1][i])
fa[c[1][i]]=1,q.push(c[1][i]);
else
c[1][i]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<m;i++)
if(c[u][i])
fa[c[u][i]]=c[fa[u]][i],q.push(c[u][i]);
else
c[u][i]=c[fa[u]][i];
}
a[1][1]=-1,a[1][tot+1]=-1;
for(int i=1;i<=tot;i++)
{
if(i>1)
a[i][i]--;
if(va[i])
continue;
for(int j=0;j<m;j++)
a[c[i][j]][i]+=p[j];
}//cerr<<tot<<endl;
gaosi(tot);
// for(int i=1;i<=tot;i++)
// {
// for(int j=1;j<=tot+1;j++)
// cerr<<a[i][j]<<" ";
// cerr<<endl;
// }
for(int i=1;i<=n;i++)
printf("%.2f\n",a[id[i]][tot+1]/a[id[i]][id[i]]);
return 0;
}

最新文章

  1. 每天一点Android干货-Activity的生命周期
  2. oracle基础备份和还原
  3. 使用openssl实现ECDSA签名以及验证功能(附完整测试源码)
  4. Web 前端开发人员和设计师必读文章推荐【系列二十八】
  5. HTML5 Canvas rect()和strokeRect() 的区别
  6. Multi-Device Hybrid Apps for Visual Studio CTP2.0
  7. boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。
  8. HDU 1815 Building roads
  9. Struts2验证
  10. UWP锁、解屏后无法响应操作
  11. Statistical Models and Social Science
  12. 移动端Touch事件基础
  13. Windows上最大传输单元MTU值的查看和设置
  14. string用法总结
  15. JAVA之字符串
  16. PMP:9.项目资源管理
  17. linux硬件数据
  18. SpringMVC简单项目配置
  19. BT656与BT1120的区别
  20. Color the ball(hdu1556)(hash)或(线段树,区间更新)

热门文章

  1. Back弹出AlertDialog
  2. PAT (Advanced Level) 1036. Boys vs Girls (25)
  3. &lt;项目&gt;&lt;day12&gt;通讯录(自己做的)
  4. 【纯净版windows系统】U盘启动制作图文教程
  5. CSS布局之BFC和IFC
  6. firedac数据集的序列和还原
  7. Making User-Managed Backups-17.3、Making User-Managed Backups of Offline Tablespaces and Datafiles
  8. 每天复习Shell—ls
  9. Codeforces Round #310 (Div. 1) C. Case of Chocolate (线段树)
  10. su: /bin/bash: Permission denied带来的疑惑