您的位置:首页 > 其它

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: