链接:点击打开链接
题意:在一个矩阵内从左上角走到右下角,向右走得到一个R向下走得到一个D,问最后有几种走到右下角时得到的字符串包含题中给出的两个字符串
代码:
#include <set>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MOD=1000000007;
struct node{
int c[2],dis,fail;
}s[205];
int n,m,rt;
int dp[105][105][205][4];
int get(char c){
if(c=='R')
return 0;
return 1;
}
void in(char ss[],int id){
int i,u;
u=0;
for(i=0;ss[i];i++){
if(s[u].c[get(ss[i])]==0)
s[u].c[get(ss[i])]=rt++;
u=s[u].c[get(ss[i])];
}
s[u].dis=(1<<id);
}
void getfail(){
int i,u,v,tmp;
queue<int> qu;
qu.push(0);
while(qu.size()){
u=qu.front();
qu.pop();
for(i=0;i<2;i++){
if(v=s[u].c[i]){
if(u==0)
s[v].fail=0;
else{
tmp=s[u].fail;
while(tmp&&s[tmp].c[i]==0)
tmp=s[tmp].fail;
s[v].fail=s[tmp].c[i];
s[v].dis|=s[s[tmp].c[i]].dis;
}
qu.push(v);
}
else
s[u].c[i]=s[s[u].fail].c[i];
}
}
}
int ac(){ //dp[i][j][k][sta]表示走到(i,j)点的
int i,j,k,ans,sta,tmp; //路径,在自动机上走到k点,状态是sta的种数
getfail();
memset(dp,0,sizeof(dp));
dp[0][0][0][0]=1;
for(i=0;i<=n;i++){
for(j=0;j<=m;j++){
for(k=0;k<rt;k++){
for(sta=0;sta<4;sta++){
if(dp[i][j][k][sta]>0){ //只有 两个字母转移
tmp=dp[i+1][j][s[k].c[1]][sta|s[s[k].c[1]].dis];
tmp=(tmp+dp[i][j][k][sta])%MOD;
dp[i+1][j][s[k].c[1]][sta|s[s[k].c[1]].dis]=tmp;
tmp=dp[i][j+1][s[k].c[0]][sta|s[s[k].c[0]].dis];
tmp=(tmp+dp[i][j][k][sta])%MOD;
dp[i][j+1][s[k].c[0]][sta|s[s[k].c[0]].dis]=tmp;
}
}
}
}
}
ans=0;
for(i=0;i<rt;i++)
ans=(ans+dp[n][m][i][3])%MOD;
return ans;
}
int main(){
int i,j,t;
char ss[105];
scanf("%d",&t);
while(t--){ //先是长,后是宽
scanf("%d%d",&n,&m);
swap(n,m);
rt=1;
memset(s,0,sizeof(s));
for(i=0;i<2;i++){
scanf("%s",ss);
in(ss,i);
}
printf("%d\n",ac());
}
return 0;
}