HDU 3689 (KMP+DP || 暴力+dp)

来源:互联网 发布:centos phpbrew 编辑:程序博客网 时间:2024/05/22 13:57

由于匹配串比较小,也可暴力
dp[i][j]表示输入第i个字符模式串匹配到第j个字符的概率。
KMP+DP如下:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>using namespace std;typedef long long LL;const int maxn = 30;char s[maxn], c[maxn];double dp[1007][maxn];double p[maxn];int Next[maxn], n, m, len;void getNext() {    Next[1] = 0;    int j = 0;    for(int i = 2; i <= len; ++i) {        while(j && s[j+1] != s[i]) j = Next[j];        if(s[j+1] == s[i]) j++;        Next[i] = j;    }}int main() {    while(scanf("%d%d", &n, &m)) {        if(!n && !m) break;        memset(dp, 0, sizeof(dp));        getchar();        for(int i = 1; i <= n; ++i) scanf("%c %lf\n", &c[i], &p[i]);        scanf("%s", s+1);        len = strlen(s+1);        getNext();        dp[0][0] = 1;        for(int i = 0; i < m; ++i) {            for(int j = 0; j < len; ++j) {                for(int k = 1; k <= n; ++k) {                    int pos = j;                    while(pos && s[pos+1] != c[k]) pos = Next[pos];                    if(s[pos+1] == c[k]) pos++;                    dp[i+1][pos] += dp[i][j]*p[k];                }            }        }        double ans = 0.0;        for(int i = 0; i <= m; ++i) ans += dp[i][len];        printf("%.2lf%%\n", ans*100);    }}
0 0