HDU 2825 Wireless Password(AC自动机+DP)

题目链接

做题,

 #include <cstdio>
#include <string>
#include <cstring>
using namespace std;
#define MOD 20090717
int trie[][];
int o[];
int fail[];
int que[];
int dp[][][];
int flag[];
int t;
void CL()
{
memset(trie,-,sizeof(trie));
memset(dp,,sizeof(dp));
memset(o,,sizeof(o));
t = ;
}
void insert(char *s,int num)
{
int root,i,len;
len = strlen(s);
root = ;
for(i = ;i < len;i ++)
{
if(trie[root][s[i]-'a'] == -)
trie[root][s[i]-'a'] = t ++;
root = trie[root][s[i]-'a'];
}
o[root] |= <<num;
}
void build_ac()
{
int head,tail,front,i;
head = tail = ;
for(i = ;i < ;i ++)
{
if(trie[][i] != -)
{
fail[trie[][i]] = ;
que[tail++] = trie[][i];
}
else
{
trie[][i] = ;
}
}
while(head != tail)
{
front = que[head++];
o[front] |= o[fail[front]];
for(i = ;i < ;i ++)
{
if(trie[front][i] != -)
{
que[tail++] = trie[front][i];
fail[trie[front][i]] = trie[fail[front]][i];
}
else
{
trie[front][i] = trie[fail[front]][i];
}
}
}
}
int main()
{
int n,m,r,k,i,j,u,x,y;
char str[];
for(i = ;i < ;i ++)
{
for(j = ;j < ;j ++)
{
if(i&(<<j)) flag[i] ++;
}
}
while(scanf("%d%d%d",&n,&m,&r)!=EOF)
{
if(n == &&m == &&r == ) break;
CL();
for(i = ;i < m;i ++)
{
scanf("%s",str);
insert(str,i);
}
build_ac();
dp[][][] = ;
x = ;y = ;
for(i = ;i < n;i ++)
{
memset(dp[y],,sizeof(dp[y]));
for(j = ;j < t;j ++)
{
for(k = ;k < (<<m);k ++)
{
if(dp[x][j][k] == ) continue;
for(u = ;u < ;u ++)
{
int temp = trie[j][u];
dp[y][temp][k|o[temp]] += dp[x][j][k];
if(dp[y][temp][k|o[temp]] >= MOD)
dp[y][temp][k|o[temp]] -= MOD;
}
}
}
swap(x,y);
}
int ans = ;
for(i = ;i < t;i ++)
{
for(j = ;j < (<<m);j ++)
{
if(flag[j] >= r)
ans = (ans + dp[x][i][j])%MOD;
}
}
printf("%d\n",ans);
}
return ;
}

找找手感。

上一篇:【leetcode】Search in Rotated Sorted Array (hard)


下一篇:Webpack4 学习笔记二 CSS模块转换