首先數據范圍很假
當\(N + M - 1 > K\)的時候就無解
所以對於所有要計算的情況,\(N + M \leq 11\)
超級小是吧,考慮搜索
對於每一個格子試填一個數
對於任意道路上不能存在兩個相同顏色的限制使用狀態壓縮進行判斷
一些必要的剪枝:
①如果當前可以放的顏色比路徑長度要短,表示剩余顏色不夠,直接return
②如果當前這一個格子為空,並且填入的是在這之前從來沒有使用過的顏色,那么對於所有沒有使用過的顏色,它們填在這一個格子的答案是一樣的,只要搜一次就可以了。
#include<bits/stdc++.h>
#define lowbit(x) ((x) & -(x))
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return f ? -a : a;
}
const int MOD = 1e9 + 7;
int arr[11][11] , f[11][11] , cnt1[1 << 10] , times[11];
int N , M , K;
int dfs(int x , int y){
if(y > M){
y = 1;
++x;
}
if(x > N)
return 1;
int s = f[x - 1][y] | f[x][y - 1] , sum = 0 , calc = 0;
if(K - cnt1[s] < N - x + M - y + 1)
return 0;
bool ff = 0;
for(int i = 0 ; i < K ; ++i)
if(!(s & (1 << i)))
if(arr[x][y] == i + 1 || arr[x][y] == 0){
f[x][y] = s | (1 << i);
if(!times[i + 1]++){
if(!ff){
calc = dfs(x , y + 1);
ff = 1;
}
sum = (sum + calc) % MOD;
}
else
sum = (sum + dfs(x , y + 1)) % MOD;
--times[i + 1];
}
return sum;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
N = read();
M = read();
K = read();
if(N + M - 1 > K){
puts("0");
return 0;
}
for(int i = 1 ; i <= N ; ++i)
for(int j = 1 ; j <= M ; ++j)
++times[arr[i][j] = read()];
for(int i = 1 ; i < 1 << K ; ++i)
cnt1[i] = cnt1[i - lowbit(i)] + 1;
cout << dfs(1 , 1);
return 0;
}