由于匹配串比较小,也可暴力
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);
}
}