您的位置:首页 > 其它

AC自动机,概率,递推(子串,UVA 11468)

2016-12-15 12:54 330 查看
一是记忆化搜索时数组开小了。

二是忘写getfail毁一生,竟然还能过样例。

本来昨天晚上就可以过掉的题目搞到今天中午。。。

感觉自己空手debug能力好差,很多逗比的错误都发现不了。真的要一步一步仔细做好了。

代码

#include<bits/stdc++.h>
#define maxn 500
#define size 62
using namespace std;

int ch[maxn][size];
int val[maxn],sz;
void init()
{
memset(ch[0],0,sizeof(ch[0]));
val[0]=0;
sz=1;
}
int idx(char x)
{
if(isdigit(x)) return x-'0';
else if('a'<=x&&x<='z') return x-'a'+10;
else return x-'A'+36;
}
void insert(char *s)
{
int l=strlen(s);
int j=0;
for(int i=0;i<l;i++)
{
int c=idx(s[i]);
if(!ch[j][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[j][c]=sz++;
}
j=ch[j][c];
}
val[j]=1;
}

int f[maxn],last[maxn];
void getfail()
{
queue<int>q;
f[0]=last[0]=0;
for(int c=0;c<size;c++) if(ch[0][c])
{
int u=ch[0][c];
f[u]=last[u]=0;
q.push(u);
}
while(!q.empty())
{
int r=q.front();
q.pop();
for(int c=0;c<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];
last[u]=val[f[u]]?f[u]:last[f[u]];
}
}
}

double p[100];
int L;

int vis[110][maxn];
double ANS[110][maxn];

double dfs(int i,int j)
{
if(vis[i][j]) return ANS[i][j];
if(i==L) return 1;
vis[i][j]=1;
double ret=0;
for(int c=0;c<size;c++)
{
if(p[c]==0) continue;
int v=j;
while(v&&!ch[v][c]) v=f[v];
v=ch[v][c];
if(!val[v]&&!val[last[v]]) ret+=p[c]*dfs(i+1,v);
/*int v=ch[j][c];
if(!v)
{
v=f[j];
while(v&&!ch[v][c]) v=f[v];
if(!val[v]) ret+=p[c]*dfs(i+1,v);
}
else if(!val[v]) ret+=p[c]*dfs(i+1,v);*/
}
return ANS[i][j]=ret;
}

int main()
{
char s[30];
int T;
scanf("%d",&T);
for(int t=1;t<=T;t++)
{
memset(vis,0,sizeof(vis));
init();
int n;
scanf("%d",&n);
while(n--)
{
scanf("%s",s);
insert(s);
}
getfail();
memset(p,0,sizeof(p));
scanf("%d",&n);
while(n--)
{
char ch;
scanf("%*c%c",&ch);
scanf("%lf",&p[idx(ch)]);
}
scanf("%d",&L);
printf("Case #%d: %lf\n",t,dfs(0,0));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: