kuangbinOJ 1216 Gambler (ac自动机+概率dp)
来源:互联网 发布:淘宝自拍风格 滤镜 编辑:程序博客网 时间:2024/05/24 05:45
题意:
两个人分别拥有两个串P,Q,现在两个人玩掷硬币游戏,从一个空串开始,如果正面向上那么就在串后面+'1'否者+'0'。一旦这串中包含了P或者Q串就停止比赛,如果包含P则A赢,包含Q则B赢,否则平局。现在问A和B赢的概率分别是多少。
题解:
这题要分别对A赢和B赢进行dp,应为有平局的情况。那对于A赢dp,将P插入自动机标记为1,插入自动机标记-1,这样在建机时就将包含P和不包含Q的分开了!然后dp[i][j]表示掷硬币第i轮,走到自动机j节点对应的概率。对于B同理。
OJ问题ac不了。
#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))void cmax(int& a,int b){ if(b>a)a=b; }void cmin(int& a,int b){ if(b<a)a=b; }typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const int MOD=2012;const int maxn=55;const int SIZE=maxn*maxn*2;char P[maxn],Q[maxn];double dp[maxn][SIZE];struct AC_Autometon{ int next[SIZE][2],fail[SIZE],flag[SIZE]; int cnt,root; int newNode(){ for(int i=0;i<2;i++) next[cnt][i]=-1; flag[cnt]=0; return cnt++; } void Init(){ cnt=0; root=newNode(); } void Insert(char buff[],int id){ int now=root; for(int i=0;buff[i];i++){ int k=buff[i]-'0'; if(next[now][k]==-1) next[now][k]=newNode(); now=next[now][k]; } flag[now]=id; } void build(){ queue<int>q; int now=root; for(int i=0;i<2;i++){ if(next[now][i]==-1) next[now][i]=root; else{ fail[next[now][i]]=root; q.push(next[now][i]); } } while(!q.empty()){ now=q.front();q.pop(); if(flag[fail[now]]!=-1) flag[now]+=flag[fail[now]]; if(flag[fail[now]]==-1) flag[now]=-1; for(int i=0;i<2;i++){ if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else{ fail[next[now][i]]=next[fail[now]][i]; q.push(next[now][i]); } } } } double DP(int n){ memset(dp,0,sizeof dp); double ans=0; dp[0][0]=1; for(int i=0;i<n;i++){ for(int j=0;j<cnt;j++){ if(flag[j]!=0)continue; for(int t=0;t<2;t++){ int k=next[j][t]; if(flag[k]!=-1) dp[i+1][k]+=dp[i][j]*0.5; } } } for(int i=1;i<=n;i++){ for(int j=0;j<cnt;j++){ if(flag[j]>0) ans+=dp[i][j]; } } return ans; } void Debug(){ for(int i=0;i<cnt;i++){ printf("%d ch[ ",i); for(int j=0;j<2;j++) printf("%d ",next[i][j]); puts("]"); } }}ac;int main(){ //freopen("G:\\read.txt","r",stdin); int K,T; double ans1,ans2; scanf("%d",&T); while(T--){ scanf("%s%s",P,Q); scanf("%d",&K); ac.Init(); ac.Insert(P,1); ac.Insert(Q,-1); ac.build(); ans1=ac.DP(K); ac.Init(); ac.Insert(Q,1); ac.Insert(P,-1); ac.build(); ans2=ac.DP(K); printf("%.9lf %.9lf\n",ans1,ans2); } return 0;}/**2010001250115*/
0 0
- kuangbinOJ 1216 Gambler (ac自动机+概率dp)
- Uva11468 AC自动机+概率dp
- UVA 11468-Substring(AC自动机+概率dp)
- UVA 11468 Substring(AC自动机+概率DP)
- UVa 11468 Substring AC自动机+概率DP
- UVA 11468 Substring AC自动机+概率DP
- UVA - 11468(简单概率dp+ac自动机)
- 【Uva11468】Substring【AC自动机】【概率DP】
- UVA 11468 Substring(AC自动机+概率DP)
- UVA 11468 - Substring (AC自动机 概率DP)
- [AC自动机+概率dp] hdu 3689 Infinite monkey theorem
- BZOJ1444 有趣的游戏【AC自动机、概率DP】
- HYSBZ 1444 有趣的游戏 AC自动机+概率DP+高斯消元
- uva 11468 ac自动机+概率DP+简单的数据生成器
- BZOJ 禁忌 AC自动机+概率DP+矩阵乘
- Uva 11468 Substring——AC自动机+概率DP
- hdu4758 AC自动机+dp
- AC自动机 + DP小结
- 关于接入新浪微博第三方登录
- hessian的使用
- shell执行scala脚本
- chromium浏览器开发系列第一篇:如何获取最新chromium源码
- 金字塔树
- kuangbinOJ 1216 Gambler (ac自动机+概率dp)
- C# Http多线程下载、断点续传
- Aweek开发笔记11.15
- JS 返回上一步(退回上一步上一个网页)
- HTML字符实体表
- Robotium学习笔记---环境搭建及入门示例
- 读书笔记之——《暗时间》
- debian安装mysql总结
- js Array Object 操作大全