n,m<=1000是在逗你玩。。。
因为n+m-1>k无解啦。。。k<=10。。。
暴力大法好。。。
我们从左上向右下枚举棋子,遵循每次只放放过的棋子或者没放过的编号最小的棋子(当然是符合题目要求的情况下),最后用组合计数搞一搞即可以啦
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
#define two(x) (1<<(x))
const int Mod=(1e9)+7;
int C[15][15],p[15][15],a[15][15],jc[15];
int ans,n,m,k,tot,cnt,i,j,k1,k2,c[100];
bool Judge(int x,int y,int c){
for (int i=x;i<=n;i++)
for (int j=y;j<=m;j++)
if (x!=i || y!=j){
if (a[i][j]==c) return 0;
if ( ( p[i][j]|two(c-1) ) == ( two(k)-1 ) ) return 0;
}
return 1;
}
void dfs(int x,int y){
if (cnt>k) return;
if (x>n){
ans=( ans+(LL)C[k-tot][cnt-tot]*jc[cnt-tot]%Mod )%Mod;
return;
}
if (a[x][y]){
dfs(x+y/m,y%m+1);
return;
}
for (int c=1;c<=cnt;c++)
if ( !(p[x][y]&two(c-1)) && Judge(x,y,c) ){
for (int i=x;i<=n;i++)
for (int j=y;j<=m;j++)
p[i][j]|=two(c-1);
dfs(x+y/m,y%m+1);
for (int i=x;i<=n;i++)
for (int j=y;j<=m;j++){
p[i][j]=p[i-1][j]|p[i][j-1];
if (a[i-1][j]) p[i][j]|=two(a[i-1][j]-1);
if (a[i][j-1]) p[i][j]|=two(a[i][j-1]-1);
}
}
cnt++;
for (int i=x;i<=n;i++)
for (int j=y;j<=m;j++)
p[i][j]|=two(cnt-1);
dfs(x+y/m,y%m+1);
for (int i=x;i<=n;i++)
for (int j=y;j<=m;j++){
p[i][j]=p[i-1][j]|p[i][j-1];
if (a[i-1][j]) p[i][j]|=two(a[i-1][j]-1);
if (a[i][j-1]) p[i][j]|=two(a[i][j-1]-1);
}
cnt--;
}
int main(){
freopen("293B.in","r",stdin);
freopen("293B.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
if (n+m-1>k){
printf("0\n",ans);
return 0;
}
for (i=1;i<=n;i++)
for (j=1;j<=m;j++){
scanf("%d",&a[i][j]);
if (a[i][j]!=0)
c[++tot]=a[i][j];
}
sort(c+1,c+tot+1);
cnt=tot=unique(c+1,c+tot+1)-c-1;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (a[i][j])
a[i][j]=lower_bound(c+1,c+tot+1,a[i][j])-c;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (a[i][j])
for (k1=i;k1<=n;k1++)
for (k2=j;k2<=m;k2++)
if (k1!=i || k2!=j)
p[k1][k2]|=two(a[i][j]-1);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (a[i][j] && (p[i][j]&two(a[i][j]-1)) )
{ puts("0"); return 0; }
for (i=0;i<=10;i++) C[i][0]=1;
for (i=1;i<=10;i++)
for (j=1;j<=i;j++)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%Mod;
for (i=1,jc[0]=1;i<=10;i++)
jc[i]=((LL)jc[i-1]*i)%Mod;
dfs(1,1);
printf("%d\n",ans);
return 0;
}