于是我们对行列分别求一遍把行列都满足的容斥掉。 那么我们枚举奇数行的两种颜色,求出这种填法下这一行下修改的个数 令
f
i
,
j
f_{i,j}
fi,j 表示到第
i
i
i 排改了
k
k
k 个位置的方案数就可以
d
p
dp
dp 复杂度
O
(
n
k
)
O(nk)
O(nk),
n
=
1
n=1
n=1 或者
m
=
1
m=1
m=1 的情况要特判掉
#include<bits/stdc++.h>#define cs const
using namespace std;
cs int K = 16, N = 105, M = 1e4 + 50;
cs int Mod = 1e9 + 7;
int add(int a, int b){return a + b >= Mod ? a + b - Mod : a + b;}
int mul(int a, int b){return 1ll * a * b % Mod;}
int dec(int a, int b){return a - b < 0 ? a - b + Mod : a - b;}
void Add(int &a, int b){ a = add(a, b);}
void Dec(int &a, int b){ a = dec(a, b);}
int n, m, k, mp[N][N];
char S[N];
int idx(char c){
if(c =='R')return 0;
if(c =='G')return 1;
if(c =='B')return 2;
if(c =='Y')return 3;}
namespace Main{
int ans, p[K], num[K][N], dp[N][M]; bool vis[K];
void matrix_work(int u, int v){
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(mp[i][j]!=((j&1)?u:v)) ++num[u*4+v][i];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(mp[i][j]!=((j&1)?v:u)) ++num[v*4+u][i];}
void work(int A, int B, int C, int D, bool FLAG, int coe){
for(int i = 0; i <= n; i++)
for(int j = 0; j <= k; j++) dp[i][j]= 0;
dp[0][0]= 1;
for(int i = 1; i <= n; i++){
int u = A, v= B;
if(i & 1 ^ 1) u = C, v= D;
int now = num[u*4+v][i];
for(int j = now; j <= k; j++) Add(dp[i][j],dp[i-1][j-now]);
if(!FLAG){
int now = num[v*4+u][i];
for(int j = now; j <= k; j++) Add(dp[i][j],dp[i-1][j-now]);}}
for(int i = 0; i <= k; i++)(coe==1) ? Add(ans,dp[n][i]): Dec(ans,dp[n][i]);}
void dfs(int u){
if(u > 4){ work(p[1],p[2],p[3],p[4],1,-1);return;}
for(int i = 0; i < 4; i++) if(!vis[i])
p[u]=i, vis[i]=true, dfs(u+1), vis[i]=false;}
void matrix_rotate(){
static int tmp[N][N];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) tmp[j][i]= mp[i][j];
swap(n, m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) mp[i][j]= tmp[i][j];}
void Solve(){
matrix_work(0,1);
matrix_work(0,2);
matrix_work(0,3);
matrix_work(1,2);
matrix_work(1,3);
matrix_work(2,3);
work(0,1,2,3,0,1);
work(0,2,1,3,0,1);
work(0,3,1,2,0,1);
work(1,2,0,3,0,1);
work(1,3,0,2,0,1);
work(2,3,0,1,0,1);
dfs(1);
matrix_rotate();
memset(num, 0, sizeof(num));
matrix_work(0,1);
matrix_work(0,2);
matrix_work(0,3);
matrix_work(1,2);
matrix_work(1,3);
matrix_work(2,3);
work(0,1,2,3,0,1);
work(0,2,1,3,0,1);
work(0,3,1,2,0,1);
work(1,2,0,3,0,1);
work(1,3,0,2,0,1);
work(2,3,0,1,0,1);
cout << ans;}}
namespace Special{
int dp[N][N][4], ans;
void Solve(){
if(m == 1) Main::matrix_rotate();
for(int i = 0; i < 4; i++) dp[1][i!=mp[1][i]][i]= 1;
for(int i = 2; i <= m; i++)
for(int j = 0; j <= k; j++)
for(int l = 0; l < 4; l++)
for(int r = 0; r < 4; r++) if(l ^ r)
Add(dp[i][j+(r!=mp[1][i])][r],dp[i-1][j][l]);
for(int i = 0; i <= k; i++)
for(int l = 0; l < 4; l++) Add(ans, dp[m][i][l]);
cout << ans;}}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++){
scanf("%s",S+1);
for(int j=1; j<=m; j++) mp[i][j]=idx(S[j]);}
if(n>1&&m>1){ Main::Solve();return 0;}
Special::Solve();return 0;}