借鉴:https://www.cnblogs.com/clrs97/p/7841819.html
#include<cstdio>
typedef long long ll;
const int N=40;
int n,m,i,j,k;
ll ans,f[N][N]; //f[i][j]表示考虑前i行,第i行前j个为B的种类,额,前0个有意思。
char a[N][N];
bool can[N][N];
inline bool check(int x,int y)
{
for(int i=1;i<=y;i++) if(a[x][i]=='R') return 0; //在j为0的情况下,只要判断后面是否出现B,有,则不可能
for(int i=y+1;i<=m;i++) if(a[x][i]=='B') return 0; //在j为m的情况下,只要判断前m个数是否出现R,有,则不可能
return 1;
}
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%s",a[i]+1); //加1就是说起点从a[1][1]开始的
for(i=1;i<=n;i++)
{
for(j=0;j<=m;j++)
{ //额,因为存在一整行都不存在B的情况,或一整行都不存在R的情况
can[i][j]=check(i,j); //can表示第i行前j个数为B能否存在,为1则存在,为0则不存在。
}
}
//f[i][j] [1..j] is B, j+1..m is R
for(j=0;j<=m;j++)f[1][j]=can[1][j];
for(i=1;i<n;i++)
for(j=0;j<=m;j++)
for(k=0;k<=j;k++)
f[i+1][k]+=f[i][j]*can[i+1][k];
for(j=0;j<=m;j++)ans+=f[n][j];
printf("%lld",ans);
}