zoukankan      html  css  js  c++  java
  • HDU 2825 Wireless Password

    题目链接:HDU-2825

    题意:给出m个单词,要构造出满足包含其中大于等于k个单词的字符串,字符只包括小写字母,问长度为n的这样的串有多少个。

    思路:令dp[i][j][k]表示当前已经构造了i个字符,在ac自动机上跑到结点j,且单词状态为k情况下的方案数。从dp[i][j][k]向dp[i+1]递推。注意单词可能重复出现。

    代码:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<vector>
      4 #include<set>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<iostream>
      9 #include<queue>
     10 using namespace std;
     11 typedef long long LL;
     12 const LL MAXN=2e3+10;
     13 const LL INF=0x3f3f3f3f;
     14 const LL MOD=20090717;
     15 
     16 struct AC
     17 {
     18     int ch[MAXN][26];
     19     vector<int> val[MAXN];
     20     int sz;
     21     AC() { init(); }
     22     void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); val[0].clear();}
     23     int idx(char c)
     24     {
     25         return c-'a';
     26     }
     27     void insert(char *s,int v)
     28     {
     29         int u=0,n=strlen(s);
     30         for(int i=0;i<n;i++)
     31         {
     32             int c=idx(s[i]);
     33             if(!ch[u][c])
     34             {
     35                 memset(ch[sz],0,sizeof(ch[sz]));
     36                 val[sz].clear();
     37                 ch[u][c]=sz++;
     38             }
     39             u=ch[u][c];
     40         }
     41         val[u].push_back(v);
     42     }
     43     int f[MAXN];
     44     int last[MAXN];
     45     void getFail()
     46     {
     47         queue<int> q;
     48         f[0]=0;
     49         for(int c=0;c<26;c++)
     50         {
     51             int u=ch[0][c];
     52             if(u) {f[u]=0;q.push(u);last[u]=0;}
     53         }
     54         while(!q.empty())
     55         {
     56             int r=q.front();q.pop();
     57             for(int c=0;c<26;c++)
     58             {
     59                 int u=ch[r][c];
     60                 if(!u)
     61                 {
     62                     ch[r][c]=ch[f[r]][c];
     63                     continue;
     64                 }
     65                 q.push(u);
     66                 int v=f[r];
     67                 while(v && !ch[v][c]) v=f[v];
     68                 f[u]=ch[v][c];
     69                 last[u]=(val[f[u]].size())?f[u]:last[f[u]];
     70             }
     71         }
     72     }
     73 };
     74 AC T;
     75 int f[2][300][3000];
     76 bool isOK(int x,int k)
     77 {
     78     int sum=0;
     79     for(int i=1;i<=10;i++)
     80         if(x&(1<<i))
     81             sum++;
     82     return sum>=k;
     83 }
     84 int main()
     85 {
     86 #ifdef LOCAL
     87     freopen("in.txt","r",stdin);
     88     // freopen("out.txt","w",stdout);
     89 #endif
     90     int n,m,K;
     91     while(scanf("%d%d%d",&n,&m,&K)!=EOF && (n || m || K))
     92     {
     93         T.init();
     94         for(int i=1;i<=m;i++)
     95         {
     96             char s[100];
     97             scanf("%s",s);
     98             T.insert(s,i);
     99         }
    100         T.getFail();
    101         memset(f,0,sizeof(f));
    102         f[0][0][0]=1;
    103         for(int i=0;i<n;i++)
    104         {
    105             for(int j=0;j<T.sz;j++)
    106                 for(int k=0;k<(1<<(m+1));k++)
    107                     f[1-i%2][j][k]=0;
    108             for(int j=0;j<T.sz;j++)
    109                 for(int k=0;k<(1<<(m+1));k++)
    110                     if(f[i%2][j][k])
    111                         for(int jj=0;jj<26;jj++)
    112                         {
    113                             int v= T.ch[j][jj];
    114                             int kk=k;
    115                             if(T.val[v].size())
    116                             {
    117                                 for(unsigned int ii=0;ii<T.val[v].size();ii++)
    118                                 {
    119                                     if((kk&(1<<T.val[v][ii]))==0)
    120                                         kk+=(1<<T.val[v][ii]);
    121                                 }
    122                             }
    123                             while(T.last[v]!=0)
    124                             {
    125                                 v=T.last[v];
    126                                 if(T.val[v].size())
    127                                 {
    128                                     for(unsigned int ii=0;ii<T.val[v].size();ii++)
    129                                     {
    130                                         if((kk&(1<<T.val[v][ii]))==0)
    131                                             kk+=(1<<T.val[v][ii]);
    132                                     }
    133                                 }
    134                             }
    135                             v=T.ch[j][jj];
    136                             f[(i+1)%2][v][kk]=(f[i%2][j][k]+f[(i+1)%2][v][kk])%MOD;
    137                         }
    138         }
    139         int ans=0;
    140         for(int i=0;i<T.sz;i++)
    141             for(int k=0;k<(1<<(m+1));k+=2)
    142                 if(isOK(k,K))
    143                     ans=(ans+f[n%2][i][k])%MOD;
    144         printf("%d
    ",ans);
    145     }
    146     return 0;
    147 }
  • 相关阅读:
    区块链简单模拟的一些资料
    解析配置文件的一段练习代码
    go语言字符串练习
    20180613更新 leetcode刷题
    啊哈 算法 中 图相关算法
    paxos 练手 推进中
    传智播客8月C/C++基础班开班
    虚拟机最佳实践:单个 VM、临时存储和已上传磁盘
    在微软平台上运行 SAP 应用程序
    了解 Windows Azure 存储的可伸缩性、可用性、持久性和计费
  • 原文地址:https://www.cnblogs.com/zarth/p/7565411.html
Copyright © 2011-2022 走看看