题目
X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。 地宫的入口在左上角,出口在右下角。小明被带到地宫的入口,国王要求他只能向右或向下行走。走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。 当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
输入格式输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)
接下来有n行数据,每行有m个整数Ci(0<=Ci<=12)代表这个格子上的宝物的价值
输出格式要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
样例输入
2 2 2
1 2
2 1
样例输出
2
样例输入
2 3 2
1 2 3
2 1 5
样例输出
d[x][y][num][maxValue] 代表走到(x,y)位置的时候手里持有num个宝贝而且最大值为maxValue的方案数.
该数组一开始初始化为-1.
代码
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define eps 10e-10
#define N 1000000007
int ans;
// d[x][y][num][maxValue] 代表走到(x,y)位置的时候手里持有num个宝贝而且最大值为maxValue的方案数.
int d[51][51][13][14];
int p[51][51];
int n, m, k;
int dfs(int x, int y, int num, int maxvalue){
if (d[x][y][num][maxvalue + 1] != -1){//表示这个状态已经访问过了,方案数已经确定了.
return d[x][y][num][maxvalue + 1];
}
int t = 0;
if (x == n - 1 && y == m - 1){
if (num == k || (num == k - 1 && p[x][y] > maxvalue))
return d[x][y][num][maxvalue + 1] = 1;
else
return d[x][y][num][maxvalue + 1] = 0;
}
if (x + 1 < n){
if (p[x][y] > maxvalue){ //如果格子中宝贝价值比小明手中的最大宝贝价值都大,就可以捡起来
t += dfs(x + 1, y, num + 1, p[x][y]);
t %= N;
}
t += dfs(x + 1, y, num, maxvalue); //当然也可以不捡起来,这样就不需要判断大小,因为反正不捡起来
t %= N;
}
if (y + 1 < m){
if (p[x][y] > maxvalue){//如果格子中宝贝价值比小明手中的最大宝贝价值都大,就可以捡起来
t += dfs(x, y + 1, num + 1, p[x][y]);
t %= N;
}
t += dfs(x, y + 1, num, maxvalue);//当然也可以不捡起来,这样就不需要判断大小,因为反正不捡起来
t %= N;
}
d[x][y][num][maxvalue + 1] = t;//最终得到的就是方案数
return d[x][y][num][maxvalue + 1];//返回方案数
}
int main(){
while (cin >> n >> m >> k){
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j)
cin >> p[i][j];
}
memset(d, -1, sizeof(d));//该数组一开始初始化为-1.
d[0][0][0][0] = dfs(0, 0, 0, -1);//因为宝贝的最小价值可以为0
cout << d[0][0][0][0] << endl;
}
return 0;
}