UVa11468 - Substring(AC+dp+概率)
2017-10-30 07:06
483 查看
题目链接
简介:
给出一些字符和各自出现的概率,随机选择L次后将得到一个长度为L的随机字符串S,
再给出K个模式串,计算S中不含任何一个模式串的概率
分析:
这道题就是文本生成器的变式
我们先把所有串扔到一个AC自动机上所有单词结尾都设成false(不能到达)
在建立fail指针的时候,用失配的可到达性维护结点的可到达性
之后就是记忆化搜索版本的dp
每随机生成一个字母,相当于在AC自动机上走了一步
设f(i,j)表示当前结点为i,还需要走j步
转移方程:f(i,j)=sum{P[i]*f(k,j-1)|k是i的后继且可到达结点}
所以我们需要一个map映射一下,构建AC自动机上以及dp都是在新的字典的基础上
简介:
给出一些字符和各自出现的概率,随机选择L次后将得到一个长度为L的随机字符串S,
再给出K个模式串,计算S中不含任何一个模式串的概率
分析:
这道题就是文本生成器的变式
我们先把所有串扔到一个AC自动机上所有单词结尾都设成false(不能到达)
在建立fail指针的时候,用失配的可到达性维护结点的可到达性
ed[ch[now][i]]|=ed[fail[ch[now][i]]]; //儿子的ed 儿子fail的ed
之后就是记忆化搜索版本的dp
每随机生成一个字母,相当于在AC自动机上走了一步
设f(i,j)表示当前结点为i,还需要走j步
转移方程:f(i,j)=sum{P[i]*f(k,j-1)|k是i的后继且可到达结点}
tip
本题的字典是给出的所以我们需要一个map映射一下,构建AC自动机上以及dp都是在新的字典的基础上
数组要开够
//这里写代码片 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<map> using namespace std; int ch[405][70]; int K,tot,fail[405],n,m; char s[21][21]; bool ed[405],vis[405][105]; double P[70],f[405][105]; map<char,int> mp; void insert(char *s) { int now=0; int len=strlen(s); for (int i=0;i<len;i++) { int x=mp[s[i]]; if (!ch[now][x]) ch[now][x]=++tot; now=ch[now][x]; } ed[now]=1; } void make() { queue<int> Q; for (int i=0;i<m;i++) if (ch[0][i]) Q.push(ch[0][i]); while (!Q.empty()) { int now=Q.front(); Q.pop(); for (int i=0;i<m;i++) { if (!ch[now][i]) { ch[now][i]=ch[fail[now]][i]; continue; } fail[ch[now][i]]=ch[fail[now]][i]; ed[ch[now][i]]|=ed[fail[ch[now][i]]]; //儿子的ed 儿子fail的ed Q.push(ch[now][i]); //容易漏写 } } } double doit(int u,int L) { if (!L) return 1.0; if (vis[u][L]) return f[u][L]; vis[u][L]=1; double &ans=f[u][L]; ans=0.0; for (int i=0;i<m;i++) //m if (!ed[ch[u][i]]) ans+=P[i]*doit(ch[u][i],L-1); return ans; } int main() { int T; scanf("%d",&T); for (int cas=1;cas<=T;cas++) { tot=0; memset(ed,0,sizeof(ed)); memset(vis,0,sizeof(vis)); memset(ch,0,sizeof(ch)); memset(fail,0,sizeof(fail)); memset(f,0,sizeof(f)); mp.clear(); scanf("%d",&K); for (int i=1;i<=K;i++) scanf("%s",&s[i]); scanf("%d",&m); for (int i=0;i<m;i++) //m个字符,重新编号 { char opt[2]; scanf("%s",&opt); scanf("%lf",&P[i]); mp[opt[0]]=i; } for (int i=1;i<=K;i++) insert(s[i]); make(); scanf("%d",&n); printf("Case #%d: %0.6lf\n",cas,doit(0,n)); } return 0; }
相关文章推荐
- UVa 11468 Substring (AC自动机+概率DP)
- UVA 11468-Substring(AC自动机+概率dp)
- UVA 11468 Substring(AC自动机+概率DP)
- AC自动机+全概率+记忆化DP UVA 11468 Substring
- UVA 11468 Substring(AC自动机+概率DP)
- Uva11468(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自动机+DP)
- UVA 11468(Substring-AC自动机上dp)[Template:AC自动机]
- UVA 11468 —— Substring(AC自动机+DP)
- UVa 11468 (AC自动机 概率DP) Substring
- uva 11468 - Substring(AC自动机+概率)
- UVA 11468 - Substring (AC自动机 概率DP)
- uva 11468 AC自动机+概率DP
- 【Uva11468】Substring【AC自动机】【概率DP】
- UVA 11468 Substring(AC自动机+dp)
- uva 11468 - Substring(AC自己主动机+概率)