hdu3689 AC自动机Dp
2013-11-18 16:01
337 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3689
题目大意
:给定n个字符出现的概率,随机敲击m次,敲出的串中包含给定子串的概率
算法
:AC自动机dp
思路
:建立AC自动机,设定状态f[step][k]表示第step步走到第k个ac自动机里的状态的概率,转移方程便是
f[step][k] = f[step –
1][trie[p].next[char]] *
prob[trie[p].next[char]];最后的答案便是sum(f[step][l])周到自动机最后一个节点的概率总和。
提交情况:Accepted
1次
收获
:the frist AC+dp
program
AC
code
#include <stdio.h>
#include <string.h>
#define MAXN (26)
#define MAXM (1010)
#define MAXL (20)
struct NODE{
int next[MAXN];
int falg;
int suffix;
int father;
}trie[MAXL * MAXN];
int ad;
charword[MAXL];
doubleprob[MAXN];
doublef[MAXM][MAXL];
intqueue[MAXL * MAXN], boo[MAXL * MAXN];
voidinsert(){
int q = 0;
for(int i = 0; word[i] != '\0'; i ++){
if(trie[q].next[word[i] -
'a'] == -1){
trie[q].next[word[i] - 'a'] =
ad;
trie[ad ++].father = q;
}
q = trie[q].next[word[i] - 'a'];
}
trie[q].falg = 1;
}
voidGet_trie_map(){
int head, tail, i, opt, g,
j;
memset(boo, 0, sizeof(boo));
head = tail = 0;
trie[0].suffix = 0;
boo[0] = 1;
for(i = 0; i < MAXN;
i ++)
if(trie[0].next[i] == -1)
trie[0].next[i] = 0;
else trie[trie[0].next[i]].suffix =
0;
queue[tail ++] = 0;
while(head <
tail){
opt = queue[head ++];
for(i = 0; i < MAXN;
i ++)
if(trie[opt].next[i]
> opt &&
!boo[trie[opt].next[i]]){
queue[tail ++] = g = trie[opt].next[i];
boo[g] = 1;
if(trie[g].suffix == -1)
trie[g].suffix = trie[trie[opt].suffix].next[i];
for(j = 0; j < MAXN;
j ++)
if(trie[g].next[j] == -1)
trie[g].next[j] = trie[trie[g].suffix].next[j];
}
}
}
voidBuilt_trie(){
scanf("%s", word);
ad = 1;
memset(trie, -1, sizeof(trie));
insert();
Get_trie_map();
}
doubleGet_ans(int
m){
int i, j, k;
double ans = 0;
memset(f, 0, sizeof(f));
f[0][0] = 1;
for(i = 0; i < m; i
++)
for(j = 0; j < ad -
1; j ++)
if(i >=
j)
for(k = 0; k < MAXN;
k ++){
int v = trie[j].next[k];
f[i + 1][v] += f[i][j] * prob[k];
}
for(i = 0; i <= m; i
++)
ans += f[i][ad - 1];
return ans;
}
int main(){
int n, m, i;
char ch[2];
double pro, ans;
while(~scanf("%d %d", &n,
&m), n &&
m){
memset(prob, 0, sizeof(prob));
for(i = 0; i < n; i
++){
scanf("%1s %lf", ch,
&pro);
prob[ch[0] - 'a'] =
pro;
}
Built_trie();
ans = Get_ans(m) * 100;
printf("%.2lf%%\n",
ans);
}
return 0;
}
题目大意
:给定n个字符出现的概率,随机敲击m次,敲出的串中包含给定子串的概率
算法
:AC自动机dp
思路
:建立AC自动机,设定状态f[step][k]表示第step步走到第k个ac自动机里的状态的概率,转移方程便是
f[step][k] = f[step –
1][trie[p].next[char]] *
prob[trie[p].next[char]];最后的答案便是sum(f[step][l])周到自动机最后一个节点的概率总和。
提交情况:Accepted
1次
收获
:the frist AC+dp
program
AC
code
#include <stdio.h>
#include <string.h>
#define MAXN (26)
#define MAXM (1010)
#define MAXL (20)
struct NODE{
int next[MAXN];
int falg;
int suffix;
int father;
}trie[MAXL * MAXN];
int ad;
charword[MAXL];
doubleprob[MAXN];
doublef[MAXM][MAXL];
intqueue[MAXL * MAXN], boo[MAXL * MAXN];
voidinsert(){
int q = 0;
for(int i = 0; word[i] != '\0'; i ++){
if(trie[q].next[word[i] -
'a'] == -1){
trie[q].next[word[i] - 'a'] =
ad;
trie[ad ++].father = q;
}
q = trie[q].next[word[i] - 'a'];
}
trie[q].falg = 1;
}
voidGet_trie_map(){
int head, tail, i, opt, g,
j;
memset(boo, 0, sizeof(boo));
head = tail = 0;
trie[0].suffix = 0;
boo[0] = 1;
for(i = 0; i < MAXN;
i ++)
if(trie[0].next[i] == -1)
trie[0].next[i] = 0;
else trie[trie[0].next[i]].suffix =
0;
queue[tail ++] = 0;
while(head <
tail){
opt = queue[head ++];
for(i = 0; i < MAXN;
i ++)
if(trie[opt].next[i]
> opt &&
!boo[trie[opt].next[i]]){
queue[tail ++] = g = trie[opt].next[i];
boo[g] = 1;
if(trie[g].suffix == -1)
trie[g].suffix = trie[trie[opt].suffix].next[i];
for(j = 0; j < MAXN;
j ++)
if(trie[g].next[j] == -1)
trie[g].next[j] = trie[trie[g].suffix].next[j];
}
}
}
voidBuilt_trie(){
scanf("%s", word);
ad = 1;
memset(trie, -1, sizeof(trie));
insert();
Get_trie_map();
}
doubleGet_ans(int
m){
int i, j, k;
double ans = 0;
memset(f, 0, sizeof(f));
f[0][0] = 1;
for(i = 0; i < m; i
++)
for(j = 0; j < ad -
1; j ++)
if(i >=
j)
for(k = 0; k < MAXN;
k ++){
int v = trie[j].next[k];
f[i + 1][v] += f[i][j] * prob[k];
}
for(i = 0; i <= m; i
++)
ans += f[i][ad - 1];
return ans;
}
int main(){
int n, m, i;
char ch[2];
double pro, ans;
while(~scanf("%d %d", &n,
&m), n &&
m){
memset(prob, 0, sizeof(prob));
for(i = 0; i < n; i
++){
scanf("%1s %lf", ch,
&pro);
prob[ch[0] - 'a'] =
pro;
}
Built_trie();
ans = Get_ans(m) * 100;
printf("%.2lf%%\n",
ans);
}
return 0;
}
相关文章推荐
- HDU3341 Lost's revenge(AC自动机&&dp)
- HDU 3341 Lost's revenge(AC自动机+DP)
- HDU 4758 Walk Through Squares && AC自动机+状压DP
- HDU 3341 Lost's revenge(AC自动机+状态压缩DP)
- HDU 2825 Wireless Password && AC自动机+状压DP
- HDU 2896 病毒侵袭(AC自动机)
- Poj 3691 & Hdu 2457 DNA repair (AC自动机+DP)
- hdu 3341 Lost's revenge(AC自动机+DP)
- HDU - 3341 Lost's revenge(AC自动机+DP)
- poj1625 Censored! AC自动机+DP
- HDU 2825 Wireless Password(AC自动机+状压DP)
- hdu4758 Walk Through Squares (AC自动机+DP)
- hdu3341Lost's revenge (AC自动机+变进制dp)
- dp 1836 Alignment
- poj 1625 AC自动机上的DP
- zoj 3494 BCD Code(AC自动机+数位dp)
- hdu 2825 Wireless Password(AC自动机+状压DP)
- Hdu 2457 DNA repair (ac自动机+dp)
- 1837&nbsp;Balance&nbsp;dp&nbsp;背包
- poj&nbsp;3034&nbsp;Whac-a-Mole&nbsp;dp