首页 > 代码库 > 【BZOJ1444】[Jsoi2009]有趣的游戏 AC自动机+概率DP+矩阵乘法
【BZOJ1444】[Jsoi2009]有趣的游戏 AC自动机+概率DP+矩阵乘法
【BZOJ1444】[Jsoi2009]有趣的游戏
Description
Input
注意 是0<=P
Output
Sample Input
Sample Output
HINT
30%的数据保证, n ≤ 2. 50%的数据保证, n ≤ 5. 100%的数据保证, n , l, m≤ 10.
题解:本题的做法真的很多啊,概率DP,期望DP,当然还有矩乘黑科技~
就是先跑AC自动机,弄出转移矩阵,然后自乘50次就行了。
#include <cstdio>#include <cstring>#include <iostream>#include <queue>using namespace std;int n,l,m,tot;double c[30],ans[20];queue<int> q;struct node{ int ch[30],fail,dan;}p[110];char str[20];struct M{ double v[110][110]; M (){memset(v,0,sizeof(v));} double* operator [](int x) {return v[x];} M operator * (M a) const { M c; for(int i=1;i<=tot;i++) for(int j=1;j<=tot;j++) for(int k=1;k<=tot;k++) c[i][j]+=v[i][k]*a[k][j]; return c; }};M x;void build(){ int i,u; q.push(1); while(!q.empty()) { u=q.front(),q.pop(); for(i=0;i<m;i++) { if(!p[u].ch[i]) { if(u==1) p[u].ch[i]=1; else p[u].ch[i]=p[p[u].fail].ch[i]; continue; } q.push(p[u].ch[i]); if(u==1) { p[p[u].ch[i]].fail=1; continue; } p[p[u].ch[i]].fail=p[p[u].fail].ch[i]; } }}int main(){ scanf("%d%d%d",&n,&l,&m); int i,j,u; double a,b; for(i=0;i<m;i++) scanf("%lf%lf",&a,&b),c[i]=a/b; for(tot=i=1;i<=n;i++) { scanf("%s",str),u=1; for(j=0;j<l;j++) { if(!p[u].ch[str[j]-‘A‘]) p[u].ch[str[j]-‘A‘]=++tot; u=p[u].ch[str[j]-‘A‘]; } p[u].dan=i; } build(); for(i=1;i<=tot;i++) { if(p[i].dan) x[i][i]=1; else for(j=0;j<m;j++) x[i][p[i].ch[j]]+=c[j]; } for(i=1;i<=50;i++) x=x*x; for(i=1;i<=tot;i++) if(p[i].dan) ans[p[i].dan]=x[1][i]; for(i=1;i<=n;i++) printf("%.2lf\n",ans[i]); return 0;}/*1 10 101 101 101 101 101 101 101 101 101 101 10AAAAAAAAAA */
【BZOJ1444】[Jsoi2009]有趣的游戏 AC自动机+概率DP+矩阵乘法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。