HDU 2825 Wireless Password(自动机+状态压缩DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2825

题意:给出m个串,求一个长度为n的串包含至少m个串中的K个。问这样的串有多少个?

思路:f[i][j][k]表示长度为i、到达自动机上的j节点、包含的状态为k的种类数。转移时,从当前节点向其next节点转移。

 
   




struct node

{

    int next[26],fail,st;



    void init()

    {

        clr(next,-1);

        fail=-1;

        st=0;

    }

};



node a[N];

int e,n,m,K,p[1300];



void init()

{

    int i;

    for(i=0;i<(1<<10);i++) p[i]=p[i>>1]+(i&1);

}





void insert(char s[],int t)

{

    int i,k,p=0;

    for(i=0;s[i];i++)

    {

        k=s[i]-'a';

        if(a[p].next[k]==-1)

        {

            a[e].init();

            a[p].next[k]=e++;

        }

        p=a[p].next[k];

    }

    a[p].st|=1<<t;

}





void build()

{

    queue<int> Q;

    int i,j,k,t,p,q;

    Q.push(0);

    while(!Q.empty())

    {

        k=Q.front();

        Q.pop();



        for(i=0;i<26;i++)

        {

            if(a[k].next[i]!=-1)

            {

                p=a[k].next[i];

                q=a[k].fail;

                if(q==-1) a[p].fail=0;

                else a[p].fail=a[q].next[i];

                a[p].st|=a[a[p].fail].st;

                Q.push(p);

            }

            else

            {

                q=a[k].fail;

                if(q==-1) a[k].next[i]=0;

                else a[k].next[i]=a[q].next[i];

            }

        }

    }

}



int f[30][150][1300];





void DP()

{

    int i,j,k,t,x,y;

    FOR0(i,n+1) FOR0(j,e) FOR0(k,(1<<m)) f[i][j][k]=0;

    f[0][0][0]=1;

    FOR0(i,n) FOR0(j,e) FOR0(k,(1<<m)) if(f[i][j][k])

    {

        FOR0(t,26)

        {

            x=a[j].next[t];

            y=a[x].st;

            (f[i+1][x][k|y]+=f[i][j][k])%=mod;

        }

    }

    int ans=0;

    FOR0(j,e) FOR0(k,(1<<m)) if(p[k]>=K)

    {

        ans+=f[n][j][k];

        ans%=mod;

    }

    PR(ans);

}



int main()

{

    init();

    while(scanf("%d%d%d",&n,&m,&K),n||m||K)

    {

        a[0].init();

        e=1;

        char s[15];

        int i;

        FOR0(i,m) RD(s),insert(s,i);

        build();

        DP();

    }

}

 
   

  

 
  

你可能感兴趣的:(password)