For this question, we consider the nature of DP
Sub-four cases
Black block right down monotone, monotone liters
There on the left
In addition, we may remember this heavy, so also will repeat demerit is the boundary line is horizontal and the vertical
And then also the all-white plus black
1 #include<bits/stdc++.h> 2 #define MAXN 2100 3 #define int long long 4 using namespace std; 5 int f[5][MAXN][MAXN]; 6 int sum[5][MAXN][MAXN]; 7 int n,m; 8 const int mod=1e9+7; 9 char c[MAXN][MAXN]; 10 int jud[2][MAXN][MAXN]; 11 int jud_sum[2][MAXN][MAXN]; 12 void work(int k,int cal) 13 { 14 f[k][0][m]=1; 15 for(int i=1;i<=n;++i)//黑色单降靠左 16 { 17 sum[k][i-1][m]=f[k][i-1][m]; 18 for(int j=m-1;j>=0;--j) 19 { 20 sum[k][i-1][j]=(sum[k][i-1][j+1]+f[k][i-1][j])%mod; 21 //printf("sum[%lld][%lld][%lld]=%lld\n",k,i-1,j,sum[k][i-1][j]); 22 } 23 for(int j=0;j<=m;++j) 24 { 25 //printf("i%lld j=%lld jud%lld %lld\n",i,j,jud[cal][i][j],(jud[cal^1][i][m]-jud[cal^1][i][j])); 26 if(j!=0) 27 if(jud[cal][i][j]!=0||(jud[cal^1][i][m]-jud[cal^1][i][j])!=0){continue;} 28 if(j==0) 29 if(jud[cal][i][j]||jud[cal^1][i][m]){continue;} 30 f[k][i][j]=sum[k][i-1][j]%mod; 31 //printf("f[%lld][%lld][%lld]=%lld\n",k,i,j,f[k][i][j]); 32 } 33 } 34 f[k+1][0][0]=1; 35 for(int i=1;i<=n;++i)//黑色单升靠左 36 { 37 sum[k+1][i-1][0]=f[k+1][i-1][0]; 38 for(int j=1;j<=m;++j) 39 { 40 sum[k+1][i-1][j]=(sum[k+1][i-1][j-1]+f[k+1][i-1][j])%mod; 41 } 42 for(int j=0;j<=m;++j) 43 { 44 if(j) 45 if(jud[cal][i][j]||(jud[cal^1][i][m]-jud[cal^1][i][j]))continue; 46 if(j==0) 47 if(jud[cal][i][j]||jud[cal^1][i][m])continue; 48 f[k+1][i][j]=sum[k+1][i-1][j]%mod; 49 //printf("f[%lld][%lld][%lld]=%lld\n",k+1,i,j,f[k+1][i][j]); 50 } 51 } 52 } 53 int ans=0; 54 int get_sum(int k,int x1,int y1,int x2,int y2) 55 { 56 if(x1>x2)return 0;if(y1>y2)return 0; 57 return (jud_sum[k][x2][y2]-jud_sum[k][x1-1][y2]-jud_sum[k][x2][y1-1]+jud_sum[k][x1-1][y1-1]+mod)%mod; 58 } 59 void work2() 60 { 61 for(int i=0;i<=n;++i) 62 { 63 if(get_sum(1,1,1,i,m)==0&&get_sum(0,i+1,1,n,m)==0) 64 { 65 ans--; 66 } 67 } 68 for(int i=0;i<=n;++i) 69 { 70 if(get_sum(0,1,1,i,m)==0&&get_sum(1,i+1,1,n,m)==0) 71 { 72 ans--; 73 } 74 } 75 for(int i=0;i<=m;++i) 76 { 77 if(get_sum(0,1,1,n,i)==0&&get_sum(1,1,i+1,n,m)==0) 78 { 79 ans--; 80 } 81 } 82 for(int i=0;i<=m;++i) 83 { 84 if(get_sum(1,1,1,n,i)==0&&get_sum(0,1,i+1,n,m)==0) 85 { 86 ans--; 87 } 88 } 89 if(get_sum(1,1,1,n,m)==0)ans++; 90 if(get_sum(0,1,1,n,m)==0)ans++; 91 } 92 signed main() 93 { 94 scanf("%lld%lld",&n,&m); 95 for(int i=1;i<=n;++i) 96 { 97 scanf("%s",c[i]+1); 98 for(int j=1;j<=m;++j) 99 { 100 jud[0][i][j]+=jud[0][i][j-1]; 101 jud[1][i][j]+=jud[1][i][j-1]; 102 jud_sum[0][i][j]=(jud_sum[0][i-1][j]+jud_sum[0][i][j-1]-jud_sum[0][i-1][j-1])%mod; 103 jud_sum[1][i][j]=(jud_sum[1][i-1][j]+jud_sum[1][i][j-1]-jud_sum[1][i-1][j-1])%mod; 104 if(c[i][j]=='B'){jud[0][i][j]++;jud_sum[0][i][j]++;} 105 if(c[i][j]=='W'){jud[1][i][j]++;jud_sum[1][i][j]++;} 106 } 107 } 108 work(1,1); 109 work(3,0); 110 for(int k=1;k<=4;++k) 111 { 112 for(int i=0;i<=m;++i) 113 { 114 ans=(ans+f[k][n][i])%mod; 115 //printf("f[%lld][%lld][%lld]=%lld\n",k,n,i,f[k][n][i]); 116 } 117 } 118 //printf("初ans=%lld\n",ans); 119 work2(); 120 printf("%lld\n",ans%mod); 121 }