这题由于是一个单词,其实直接kmp+dp也无妨。建立自动机当然也是可以的。设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入的长度,len是单词的长度。转移方程见代码,即在一个节点的位置时,枚举下一步的走法,乘以这种走法的概率即是对下一个状态的概率贡献。

  其实自动机的fail指针跳转的位置即是kmp中nxt数组跳转的位置。

  代码如下:

     {
while(j && word[j+] != word[i]) j = nxt[j];
if(word[j+] == word[i]) j++;
nxt[i] = j;
}
} int main()
{
while(scanf("%d%d",&n,&m) == )
{
if(n== && m==) break;
char s[];
for(int i=;i<=n;i++)
{
scanf("%s%lf",s,p+i);
c[i] = s[];
}
scanf("%s",word+);
len = strlen(word+);
get_nxt();
memset(dp,,sizeof dp);
dp[][] = 1.0;
for(int i=;i<m;i++)
{
for(int j=;j<len;j++)
{
for(int k=;k<=n;k++)
{
int pos = j;
while(pos && word[pos+] != c[k]) pos = nxt[pos];
if(word[pos+] == c[k]) pos++;
dp[i+][pos] += dp[i][j] * p[k];
}
}
}
double ans = 0.0;
for(int i=;i<=m;i++) ans += dp[i][len];
printf("%.2f%%\n",ans*100.0);
}
return ;
}

kmp+dp

 #include <bits/stdc++.h>
using namespace std;
const int MAX_Tot = + ; int n,m,len;
double p[];
char word[];
int nxt[];
double dp[][]; struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'a'])
stateTable[now].nxt[c-'a'] = size++;
now = stateTable[now].nxt[c-'a'];
}
stateTable[now].cnt++;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
/*****建立自动机nxt指针*****/
else
{
if(u == ) stateTable[u].nxt[i] = ;
else
{
int p = stateTable[u].fail;
while(p != - && stateTable[p].nxt[i] == ) p = stateTable[p].fail;
if(p == -) stateTable[u].nxt[i] = ;
else stateTable[u].nxt[i] = stateTable[p].nxt[i];
}
}
/*****建立自动机nxt指针*****/
}
}
}
}aho; int main()
{
while(scanf("%d%d",&n,&m) == )
{
if(n== && m==) break;
aho.init();
char s[];
memset(p,,sizeof p);
for(int i=;i<=n;i++)
{
double t;
scanf("%s%lf",s,&t);
p[s[]-'a'] = t;
}
scanf("%s",word+);
aho.insert(word+); aho.build();
memset(dp,,sizeof dp);
dp[][] = 1.0;
int sz = aho.size-;
for(int i=;i<m;i++)
{
for(int j=;j<sz;j++)
{
for(int k=;k<;k++)
{
int v = aho.stateTable[j].nxt[k];
dp[i+][v] += dp[i][j] * p[k];
}
}
}
double ans = 0.0;
for(int i=;i<=m;i++) ans += dp[i][sz];
printf("%.2f%%\n",ans*100.0);
}
return ;
}

自动机+dp

最新文章

  1. [LeetCode] Design Tic-Tac-Toe 设计井字棋游戏
  2. Android标题栏最右边添加按钮
  3. 【小白的CFD之旅】02 江小白
  4. CentOS7源码编译安装Postgresql9.5
  5. 让那些为Webkit优化的网站也能适配IE10(转载)
  6. Effective C++ 之 0 导读(Introduction)
  7. Mars的自语重出江湖,祝大家端午节安康
  8. (转)Java并发编程:volatile关键字解析
  9. hdu 2085
  10. tools/build.c
  11. [LeetCode]题解(python):003-Longest Substring Without Repeating Characters
  12. Django操作model时刻,一个错误:AttributeError:’ProgrammingError’ object has no attribute ‘__traceback__’
  13. jQuery幻灯片插件Skippr
  14. .NET Core log4net 使用
  15. 微信小程序开发05-日历组件的实现
  16. kubernetes调度pod运行于master节点上
  17. 架构设计---soa与msa的概念(转)
  18. Windows启动配置数据(BCD)存储文件包含一些无效信息
  19. mysql真的不能做搜索引擎吗?
  20. 转:&quot;为自动填充列调整大小期间不能执行此操作&quot;解决办法 .

热门文章

  1. CF336C-Vasily the Bear and Sequence题解--贪心
  2. 3. Java开发环境的搭建:安装JDK,配置环境变量
  3. [转载]目标检测-Selective Search
  4. 启动tomcat提示某个端口被占用
  5. oracle的listagg函数
  6. 利用django 实现个人博客 全记录(二)
  7. springboot Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
  8. CDH5.16.1的agent启动报错:ERROR Error, CM server guid updated, expected d9bcadb4-f983-41b8-a667-66760f47bc91, received a67f5efa-8473-4f6a-94d6-231d1f432ef0
  9. 《设计模式之美》 &lt;02&gt;评判代码质量好坏的维度
  10. redis写入性能测试