提议大致是给n,m,再给两个非空的不相同的只包含R或D字符串s1,s2,问用n个R,m个D可以组成多少种包含s1,s2的字符串。大致思路的话,先根据两个字符串构造trie图,其实就是把失配函数优化掉的ac自动机。之后用dp[i][x][y][k]表示在自动机上状态i,用x个R,y个D,包含s1,s2的状态.令初值dp[0][0][0][0]=1,向上DP,最后统计dp[i][n][m][3](0<=i<top)的和即可。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <memory.h>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=420;
const int tk=2;
int tree[maxn][tk];
int val[maxn];
int last[maxn];
int f[maxn];
int n,m,p,q,k;
int top;
int dp[220][110][110][4];
int ok[maxn];
const int mod=1000000007;
inline int idx(char s)
{
if (s=='R') return 0;
return 1;
}
struct autoAC
{
void init()
{
top=1;
tree[0][0]=tree[0][1]=0;
memset(val,0,sizeof val);
memset(f,0,sizeof f);
memset(last,0,sizeof last);
}
void insert(char* s,int rank)
{
int rt,nxt;
for (rt=0; *s; rt=nxt,++s)
{
nxt=tree[rt][idx(*s)];
if (nxt==0)
{
tree[rt][idx(*s)]=nxt=top;
tree[top][0]=tree[top][1]=0;
top++;
}
}
val[rt]=rank;
}
void getFail()
{
queue<int> q;
f[0]=0;
for (int c=0; c<tk; c++)
{
int u=tree[0][c];
if (u)
{
q.push(u);
f[u]=0;
last[u]=0;
}
}
while(!q.empty())
{
int r=q.front();
q.pop();
for (int c=0; c<tk; c++)
{
int u=tree[r][c];
if (!u)
{
tree[r][c]=tree[f[r]][c];
continue;
}
q.push(u);
int v=f[r];
while(v && !tree[v][c]) v=f[v];
f[u]=tree[v][c];
last[u]=val[f[u]]? f[u] : last[f[u]];
}
}
}
}ac;
int tt;
int mx,my;
char s[105],ss[105],str[105];
inline void work()
{
memset(ok,0,sizeof ok);
for (int i=0; i<top; i++)
{
int j=last[i];
ok[i]=val[i];
while(j)
{
ok[i]=ok[i]|val[j];
j=last[j];
}
}
dp[0][0][0][0]=1;
int sta;
for (int x=0; x<=mx; x++)
for (int y=0; y<=my; y++)
for (int i=0; i<top; i++)
for (int k=0; k<4; k++)
{
if (dp[i][x][y][k]==0) continue;
if (x<mx)
{
int nxt=tree[i][0];
sta=k|ok[nxt];
dp[nxt][x+1][y][sta]+=dp[i][x][y][k];
if (dp[nxt][x+1][y][sta]>=mod) dp[nxt][x+1][y][sta]-=mod;
}
if (y<my)
{
int nxt=tree[i][1];
sta=k|ok[nxt];
dp[nxt][x][y+1][sta]+=dp[i][x][y][k];
if (dp[nxt][x][y+1][sta]>=mod) dp[nxt][x][y+1][sta]-=mod;
}
}
ll res=0;
for (int i=0; i<top; i++)
{
res+=dp[i][mx][my][3];
// if (res>=mod) res-=mod;
}
res%=mod;
cout<<res<<endl;
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&tt);
while(tt--)
{
ac.init();
scanf("%d%d",&mx,&my);
for (int i=1; i<=2; i++)
{
scanf("%s",s);
ac.insert(s,i);
}
ac.getFail();
memset(dp,0,sizeof dp);
work();
}
return 0;
}