状态表示:f(i, j, k, c) 表示走到(i, j)格子,已经取到k件宝物,并且最后一件宝物的价值为c的所有取法的集合,存储数量属性
状态计算:集合划分
(f(i, j, k, c)=) 集合中所有的数量加起来
通过集合分析得到状态转移方程:
(
f(i, j, k, c) = f(i-1,j,k,c) + f(i,j-1,k,c) + delta ,\
其中 delta = f(i,j-1,k-1,c') + f(i-1,j,k-1,c'),(k>0,c'=0,1,2,...,c-1)\
f(1, 1,1,w[1][1]) = 1,f(1,1,0,0) = 1
)
#include<iostream>
using namespace std;
const int N = 60, MOD = 1000000007;
int n, m, k;
int f[N][N][13][14];
int w[N][N];
int main(){
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++){
cin >> w[i][j];
w[i][j] ++;
}
f[1][1][1][w[1][1]] = 1;
f[1][1][0][0] = 1;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++){
if(i == 1 && j == 1) continue;
for(int k = 0; k <= 12; k ++) // 此处可以只循环到输入的k为止
for(int c = 0; c <= 13; c ++){
int &val = f[i][j][k][c];
val = (val + f[i][j - 1][k][c]) % MOD;
val = (val + f[i - 1][j][k][c]) % MOD;
if(k > 0 && w[i][j] == c)
for(int _c = 0; _c < c; _c ++){
val = (val + f[i][j - 1][k - 1][_c]) % MOD;
val = (val + f[i - 1][j][k - 1][_c]) % MOD;
}
}
}
int res = 0;
for(int i = 1; i <= 13; i ++) res = (res + f[n][m][k][i]) % MOD; //统计符合条件的答案
cout << res;
}