ac自动机+dp, 和uva11468 Substring 几乎一样,但访问数组d[1010][30]时,下标写反了,但是结果不对,但是没有报错,表示不解
const int MAX = 30;
const int SIGMEA_SIZE = 26;
int m, L;
//double dp[1010][30];
double d[1010][30];
bool vis[1010][30];
char ca[30];
char a[30];
double b[30];
struct AC{
int ch[MAX][SIGMEA_SIZE];
int val[MAX];
int f[MAX];
int sz;
///trie;
void init()
{
sz=1;
memset(ch,0,sizeof(ch));
memset(val,0,sizeof(val));///
}///init;
int idx(char c) { return c-'a'; }
void insert(char *s,int v)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int c=idx(s[i]);
if(!ch[u][c])
ch[u][c] = sz++;
u = ch[u][c];
}
val[u] = v;///
}
///bfs,fail[];
void getFail()
{
queue<int> q;
f[0] = 0;///
//初始化队列
for(int c = 0; c < SIGMEA_SIZE; c++)
{
int u = ch[0][c];
if(u) { f[u] = 0; q.push(u); }///
}
while(!q.empty())
{
int r = q.front(); q.pop();
for(int c = 0; c < SIGMEA_SIZE; c++)
{
int u = ch[r][c];
if(!u) { ch[r][c] = ch[f[r]][c]; continue; }///不存在边时,也计算上;
q.push(u);
int v = f[r];
while(v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
val[u] |= val[f[u]];
}
}
}
///dp[l, u]表示敲到l的长度,在状态u位置时的概率
// double solve()
// {
// CLR(dp, 0);
// dp[0][0] = 1.0;
// REP(i, L)
// {
// REP(j, sz - 1)///!!!
// {
// if (i >= j)
// {
// REP(r, m)
// {
// int c = idx(a[r]);
// int v = ch[j][c];
// dp[i + 1][v] += b[c] * dp[i][j];
// }
// }
// }
// }
// double ans = 0.0;
// FE(i, 1, L)
// ans += dp[i][sz - 1];
// printf("%.2lf%%\n", ans * 100);
// }
///dp[l, u]表示从状态u出发,敲l的长度,包含串的概率
///含的概率,最后 dpf(L, 0)
// double dpf(int l, int u)
// {
// if (l <= 0) return 0.0;
// if (vis[l][u]) return d[l][u];
// vis[l][u] = 1;
// double &ans = d[l][u];
// ans = 0.0;
// REP(i, m)
// {
// int c = idx(a[i]);
// int v = ch[u][c];
// if (val[v]) ans += b[c];
// else ans += b[c] * dpf(l - 1, v);
// }
// return ans;
// }
///不含的概率,最后1.0 - dpf(L, 0)
double dpf(int l, int u)
{
if (l <= 0) return 1.0;
if (vis[l][u]) return d[l][u];
vis[l][u] = 1;
double &ans = d[l][u];
ans = 0.0;
REP(i, m)
{
int c = idx(a[i]);
int v = ch[u][c];
if (!val[v]) ans += b[c] * dpf(l - 1, v);
}
return ans;
}
}ac;
int main()
{
while (cin >> m >> L && (m || L))
{
ac.init();
REP(i, m)
{
scanf(" %c", &a[i]);
scanf("%lf", &b[a[i] - 'a']);
}
RS(ca);
ac.insert(ca, 1);
ac.getFail();
CLR(vis, 0);
// ac.solve();
// printf("%.2lf%%\n", (ac.dpf(L, 0)) * 100);
printf("%.2lf%%\n", (1.0 - ac.dpf(L, 0)) * 100);
}
}