您的位置:首页 > 其它

【uva11468-Substring】AC自动机+dp

2016-07-19 22:01 309 查看
http://acm.hust.edu.cn/vjudge/problem/31655


题意:给定k个模板串,n个字符以及选择它的概率pro[i],要构造一个长度问L的字符串s,问s不包含任意一个模板串的概率。

题解:

ed[i]标记trie上的点i是不是任意一个模板串的结尾(在求fail的时候ed[i]|=ed[i.fail])
d[i][l]表示从i出发还要走l步,构造的串不含模板串的概率,dp一下。注意清零。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;

const int N=30,L=110,S=66;
char s[L];
int cnt[N*L];
double d[N*L][L],pro[70];
bool ed[N*L];
queue<int> q;
int num,k,n,l;
struct node{
int son[70];
int fail;
}a[N*L];

int idx(char c)
{
if(c<='z' && c>='a') return c-'a'+1;
if(c<='Z' && c>='A') return c-'A'+27;
return c-'0'+53;
}

void clear(int x)
{
a[x].fail=0;
memset(a[x].son,0,sizeof(a[x].son));
}

void trie(char *c)
{
int l=strlen(c);
int x=0;
for(int i=0;i<l;i++)
{
int t=idx(c[i]);
if(!a[x].son[t])
{
num++;
clear(num);
a[x].son[t]=num;
}
x=a[x].son[t];
}
ed[x]=1;
}

void buildAC()
{
while(!q.empty()) q.pop();
for(int i=1;i<=S;i++)
if(a[0].son[i]) q.push(a[0].son[i]);
while(!q.empty())
{
int x=q.front();q.pop();
int fail=a[x].fail;
for(int i=1;i<=S;i++)
{
int y=a[x].son[i];
if(y)
{
a[y].fail=a[fail].son[i];
ed[y]|=ed[a[fail].son[i]];
q.push(y);
}
else a[x].son[i]=a[fail].son[i];
}
}
}

double count(int x,int l)
{
if(l==0) return d[x][l]=1.0;
if(d[x][l]!=-1) return d[x][l];
d[x][l]=0;
for(int i=1;i<=S;i++)
{
if(!pro[i]) continue;
int y=a[x].son[i];
if(!ed[y]) d[x][l]+=pro[i]*count(y,l-1);
}
return d[x][l];
}

int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int T,cas=0;
scanf("%d",&T);
while(T--)
{
num=0;
clear(0);
memset(cnt,0,sizeof(cnt));
memset(ed,0,sizeof(ed));
memset(pro,0,sizeof(pro));
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
scanf("%s",s);
trie(s);
}
buildAC();
scanf("%d",&n);getchar();
for(int i=1;i<=n;i++)
{
char c;
scanf("%c",&c);getchar();
scanf("%lf",&pro[idx(c)]);getchar();
}
scanf("%d",&l);
for(int i=0;i<=num;i++)
for(int j=0;j<=l;j++)
d[i][j]=-1;
printf("Case #%d: %lf\n",++cas,count(0,l));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: