UVa 11468 (AC自动机 概率DP) Substring
2024-10-13 20:27:34
将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点。
然后问题就变成了在Tire树上走L步且不经过禁止节点的概率。
根据全概率公式用记忆化搜索求解。
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; const int maxnode = ;
const int sigma_size = ;
int idx[]; struct AhoCorasickAutomata
{
int ch[maxnode][sigma_size];
int match[maxnode];
int f[maxnode];
int sz; void init() { sz = ; memset(ch[], , sizeof(ch[])); } void insert(char* s)
{
int u = , n = strlen(s);
for(int i = ; i < n; i++)
{
int c = idx[s[i]];
if(!ch[u][c])
{
memset(ch[sz], , sizeof(ch[sz]));
match[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
match[u] = ;
} void getFail()
{
queue<int> q;
f[] = ;
for(int c = ; c < sigma_size; c++)
{
int u = ch[][c];
if(u) { f[u] = ; q.push(u); }
}
while(!q.empty())
{
int r = q.front(); q.pop();
for(int c = ; c < sigma_size; c++)
{
int u = ch[r][c];
if(!u) { ch[r][c] = ch[f[r]][c]; continue; }
q.push(u);
int v = f[r];
while(v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
match[u] |= match[f[u]];
}
}
}
}ac; int n;
const int maxl = + ;
char s[][];
double prob[sigma_size]; int vis[maxnode][maxl];
double d[maxnode][maxl]; double getProb(int u, int L)
{
if(L == ) return 1.0;
if(vis[u][L]) return d[u][L];
vis[u][L] = ;
double& ans = d[u][L];
ans = ;
for(int c = ; c < n; c++)
if(!ac.match[ac.ch[u][c]])
ans += prob[c] * getProb(ac.ch[u][c], L-);
return ans;
} int main()
{
//freopen("in.txt", "r", stdin); int T;
scanf("%d", &T);
for(int kase = ; kase <= T; kase++)
{
int k, L;
scanf("%d", &k);
for(int i = ; i < k; i++) scanf("%s", s[i]); scanf("%d", &n);
for(int i = ; i < n; i++)
{
char s1[];
scanf("%s%lf", s1, &prob[i]);
idx[s1[]] = i;
} ac.init();
for(int i = ; i < k; i++) ac.insert(s[i]);
ac.getFail();
scanf("%d", &L);
memset(vis, , sizeof(vis));
printf("Case #%d: %.6f\n", kase, getProb(, L));
} return ;
}
代码君
最新文章
- JS瀑布流布局
- Android之Socket通信、List加载更多、Spinner下拉列表
- word-wrap&;&;word-break,奇偶行、列设置样式
- WCF使用小结:(1)WCF接收HTTP POST数据的处理方法
- vcffilter 工具bug以及解决办法
- leetcode 38 Count and Say ---java
- pragma mark - 合成图
- 动态调用WCF服务
- HDFS的shell操作
- 打造自己博客(wordpress)的wap手机版本
- VIJOS1107 求树的最长链
- Linux下tomcat的安装详解
- [转]浅谈C++指针直接调用类成员函数
- UML类图10分钟快速入门 - From 圣杰
- Ubuntu 离线安装 docker
- MySQL之You can't specify target table for update in FROM clause解决办法
- sklearn 岭回归
- jupyter环境安装
- Linux服务器没有GUI的情况下使用matplotlib绘图
- 【BZOJ】【1923】【Sdoi2010】外星千足虫
热门文章
- 腾讯开源的轻量级CSS3动画库:JX.Animate
- 还原TexturePacker plist 文件以及图片的方法 (切开各小图片)
- Nginx SPDY Pagespeed模块编译——加速网站载入
- 企业级Java应用最重要的4个性能指标
- C#索引器及示例
- sparksql链接mysql
- [你必须知道的.NET]第三十五回,判断dll是debug还是release,这是个问题
- 使用secureCRT远程Linux,出现远程主机拒绝连接
- 李洪强漫谈iOS开发[C语言-041]-计算月份天数
- lintcode: 最长无重复字符的子串