标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4758
2 3 2 RRD DDR 3 2 R D
1 10
/** hdu 4758 AC自动机+状态压缩DP 题目大意:给定一个n*m的棋盘,要求从左上角走到右下角,每次只能向下或者向右走。给定两个模式串,问有多少种走法 满足每一种走法含有这两个模式串作为子串 解题思路:构造自动机,状态压缩包含的子串。 dp[x][y][i][k] 四维DP,表示R的个数是x,D的个数是y, i是在AC自动机上的节点编号。k 是状态压缩。 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <vector> #include <queue> #include <iostream> using namespace std; const int mod=1e9+7; int dp[110][110][220][4]; int n,m; struct Trie { int next[420][2],fail[420],end[420]; int root,L; int change(char ch) { if(ch=='R')return 0; return 1; } int newnode() { for(int i=0; i<2; i++) { next[L][i]=-1; } end[L++]=0; return L-1; } void init() { L=0; root=newnode(); } void insert(char *buf,int id) { int len=strlen(buf); int now=root; for(int i=0; i<len; i++) { if(next[now][change(buf[i])]==-1) next[now][change(buf[i])]=newnode(); now=next[now][change(buf[i])]; } end[now]|=(1<<id); } void build() { queue<int>Q; fail[root]=root; for(int i=0; i<2; i++) { if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; Q.push(next[root][i]); } } while(!Q.empty()) { int now=Q.front(); Q.pop(); end[now]|=end[fail[now]]; for(int i=0; i<2; i++) { if(next[now][i]==-1) { next[now][i]=next[fail[now]][i]; } else { fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } } int solve() { memset(dp,0,sizeof(dp)); dp[0][0][0][0]=1; for(int x=0; x<=n; x++) { for(int y=0; y<=m; y++) { // printf("**\n"); for(int i=0; i<L; i++) { for(int k=0; k<4; k++) { if(dp[x][y][i][k]==0)continue; if(x<n) { int nxt=next[i][0]; dp[x+1][y][nxt][k|end[nxt]]+=dp[x][y][i][k]; dp[x+1][y][nxt][k|end[nxt]]%=mod; } if(y<m) { int nxt=next[i][1]; dp[x][y+1][nxt][k|end[nxt]]+=dp[x][y][i][k]; dp[x][y+1][nxt][k|end[nxt]]%=mod; } } } } } int ret=0; for(int i=0; i<L; i++) { ret+=dp[n][m][i][3]; ret%=mod; } return ret; } } ac; char str[210]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); ac.init(); for(int i=0; i<2; i++) { scanf("%s",str); ac.insert(str,i); } ac.build(); printf("%d\n",ac.solve()); } return 0; }
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/45476405