您的位置:首页 > 其它

HDU 4758 Walk Through Squares(AC自动机+DP)

2013-09-25 14:27 344 查看
题目链接

难得出一个AC自动机,我还没做到这个题呢。。。这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊。。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define MOD 1000000007
int dp[101][101][201][4];
int trie[201][2];
int o[201];
int fail[201],que[1001],p[201][201];
int t;
void CL()
{
t = 1;
memset(trie,-1,sizeof(trie));
memset(o,0,sizeof(o));
memset(p,0,sizeof(p));
}
void insert(char *s,int x)
{
int i,root,len,temp;
len = strlen(s);
root = 0;
for(i = 0; i < len; i ++)
{
temp = s[i] == 'D' ? 1:0;
if(trie[root][temp] == -1)
trie[root][temp] = t ++;
root = trie[root][temp];
}
o[root] = 1<<x;
}
void build_ac()
{
int head,tail,front,i;
head = tail = 0;
for(i = 0; i < 2; i ++)
{
if(trie[0][i] != -1)
{
fail[trie[0][i]] = 0;
que[tail++] = trie[0][i];
}
else
trie[0][i] = 0;
}
while(head != tail)
{
front = que[head++];
o[front] |= o[fail[front]];
for(i = 0; i < 2; i ++)
{
if(trie[front][i] != -1)
{
que[tail++] = trie[front][i];
fail[trie[front][i]] = trie[fail[front]][i];
}
else
{
trie[front][i] = trie[fail[front]][i];
}
}
}
}
int main()
{
int cas,i,j,k,u,n,m,temp;
char str[101];
scanf("%d",&cas);
while(cas--)
{
CL();
scanf("%d%d",&n,&m);
for(i = 0; i < 2; i ++)
{
scanf("%s",str);
insert(str,i);
}
for(i = 0; i <= n; i ++)
{
for(j = 0; j <= m; j ++)
{
for(k = 0; k < t; k ++)
{
for(u = 0; u < 4; u ++)
dp[i][j][k][u] = 0;
}
}
}
build_ac();
dp[0][0][0][0] = 1;
for(i = 0; i <= n; i ++)
{
for(j = 0; j <= m; j ++)
{
for(k = 0; k < t; k ++)
{
for(u = 0; u < 4; u ++)
{
if(i != n)
{
temp = trie[k][0];
dp[i+1][j][temp][u|o[temp]] = (dp[i+1][j][temp][u|o[temp]] + dp[i][j][k][u])%MOD;
}
if(j != m)
{
temp = trie[k][1];
dp[i][j+1][temp][u|o[temp]] = (dp[i][j+1][temp][u|o[temp]] + dp[i][j][k][u])%MOD;
}
}
}
}
}
int ans = 0;
for(i = 0; i < t; i ++)
{
ans = (ans + dp
[m][i][3])%MOD;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: