UVa 11468 Substring
来源:互联网 发布:安卓转java工具 编辑:程序博客网 时间:2024/04/29 11:26
题意:给出一些字符和对应的选择概率,随机选择L次后得到一个长度为L的随机字符串S。给k个模板串,计算S不包含任何一个串的概率。
思路:AC自动机+概率dp。之前我做这题一直WA,然后稍微改改代码交了下杭电上类似的题目居然1A了。。后来我才发现原因,是搜到字典树中间非叶子节点了以后,也应该试着往回跳,看看能不能跳到某个模板的末尾。但是杭电那题只有一个模板,所以才A掉的。不过杭电的题目背景比较有意思,好像是一个我小时候听过的故事,如果一个猴子随机敲键盘,可以敲出世界上任何一篇文章。。。
回到正题。这题先建立一个AC自动机,然后从字典树树根开始,走L步,如果走到模板串的末尾,就不能再走下去了,边走边算概率。我是用递推dp来做的,dp(i,j)表示走到字典树的第i个节点,已经走了j步的概率。毕竟dp(i,j)有多条路线可以到达,全部加在一起算比较省时间,如果一条路走L步走到底会超时的。要注意的是,走到某个节点时,它本身不是模板串末尾并不代表可以继续走下去,应该往回跳看看是否会遇到模板串的末尾。最后结果是sum(dp(i,L))(i取所有的树节点)。
#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> #include <iomanip> #include <cstdlib> #include <string> #include <memory.h> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <ctype.h> #define INF 1<<30 #define ll long long #define max3(a,b,c) max(a,max(b,c)) using namespace std;#define maxnode 1010int T; //50int k; //20;int n; //int L;bool valid[65];double p[65];double dp[maxnode][110];int char2int(char c){if(c>='a'&&c<='z')return c-'a';if(c>='A'&&c<='Z')return c-'A'+26;if(c>='0'&&c<='9')return c-'0'+52;return -1; }// acint val[maxnode];int vis[maxnode][110];int ch[maxnode][65];int next[maxnode];int sz;double ans;void init(){sz=1;memset(ch[0],0,sizeof(ch[0]));memset(next,0,sizeof(next));memset(val,0,sizeof(val));}void insert(char* str){int u=0;int len=strlen(str);for(int i=0;i<len;i++){int v=char2int(str[i]);if( !ch[u][v] ){ch[u][v]=sz;memset(ch[sz],0,sizeof(ch[sz]));val[sz]=0;sz++;}u=ch[u][v];}val[u]++;}void build_ac(){memset(next,0,sizeof(next));queue<int> que; que.push(0);while(!que.empty()){int u=que.front(); que.pop();for(int i=0;i<62;i++){int v=ch[u][i];if(!v)continue;if(!u){next[v]=0;que.push(v);}else{int k=next[u];while(k&&!ch[k][i]){k=next[k];}if(ch[k][i])k=ch[k][i];next[v]=k;//cout<<"next "<<v<<" = "<<k<<endl;que.push(v);}}}}//ac endint main(){scanf("%d",&T);int cas=0;while(T--){cas++;memset(valid,0,sizeof(valid));memset(vis,0,sizeof(vis));ans=0;init();//scanf("%d",&k);for(int i=1;i<=k;i++){char pattern[30];scanf("%s",pattern);insert(pattern);}build_ac();//scanf("%d",&n);for(int i=1;i<=n;i++){char a;double b;cin>>a>>b;valid[char2int(a)]=1;p[char2int(a)]=b;}//scanf("%d",&L);for(int i=0;i<maxnode;i++){for(int j=0;j<=L;j++)dp[i][j]=0.0;}dp[0][0]=1.0; vis[0][0]=1;for(int i=1;i<=L;i++){for(int j=0;j<maxnode;j++){if(!vis[j][i-1])continue;for(int k=0;k<62;k++){if(!valid[k])continue;int v=j;while(v&&!ch[v][k]){v=next[v];}if(ch[v][k])v=ch[v][k];int tmp=v;bool skip=0;while(tmp){if(val[tmp]){skip=1;break;}tmp=next[tmp];}if(skip)continue;dp[v][i]+=dp[j][i-1]*p[k];vis[v][i]=1;}}}for(int i=0;i<maxnode;i++){ans+=dp[i][L];}printf("Case #%d: %.6lf\n",cas,ans);}return 0;}
0 0
- UVA - 11468 Substring
- UVA 11468 - Substring
- UVa 11468 Substring
- UVa 11468 Substring
- UVA 11468 Substring
- UVA 11468 Substring AC自动机
- UVA 11468 - Substring(AC自动机)
- Uva 11468 Substring (AC自动机)
- UVA 11468 Substring(AC自动机 + dp)
- UVA 11468-Substring(AC自动机+概率dp)
- UVA 11468 Substring(AC自动机+概率DP)
- UVa 11468 Substring AC自动机+概率DP
- UVA - 11468 Substring,AC自动机 + DP
- uva 11468 - Substring(AC自动机+概率)
- 【UVA】11468-Substring(AC自动机)
- UVA 11468 Substring(AC自动机+dp)
- UVA 11468 Substring AC自动机+概率DP
- UVA - 11468 Substring ( AC自动机 + dp)
- SQL*Net message to client wait isn’t really what it’s thought to be
- NSBundle
- js设置cookie
- bzoj2719[Violet 4]银河之星
- ios命令行发送推送
- UVa 11468 Substring
- LungoJS框架学习笔记——基本布局
- Python入门经典笔记之安装numpy和matplotlib遇到的问题
- rman的自动备份
- 认识<![CDATA[ ]]>
- 2015 电子科大校园招聘名单(更新中)
- MyEclipse快捷键、提示键、关键字颜色等配置
- mysql 命令行 中文报 1366错误
- 计算机视觉目标检测的框架与过程