地宫取宝
X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
输入
输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)
接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
输出
要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
样例输入
2 3 2
1 2 3
2 1 5
样例输出
14
解法:
dfs,注意过程中完成记录当前的宝物数值,,拿不拿的状态
import java.util.Scanner;
public class Main{
private static int n;
private static int m;
private static int k;//k件宝物
private static int[][] data;
private static int count = 0;
private static boolean pandaun(int i,int j,int k_count,int[] baowu) { //判断这个宝物可不可以取
int flag = 1;
for(int di=0;di<k_count;di++) {
if(data[i][j]<=baowu[di]) {
flag = 0;
break;
}
}
if(flag==1) {
return true;
}
return false;
}
private static void dfs(int i,int j,boolean na,int k_count ,int[] baowu) {//na代表取不取,k_count代表当前存储的宝物下标,baowu数组代表当前存储的所有宝物
if(na) {
baowu[k_count] = data[i][j]; //把要拿的宝物放进去
k_count++;
}
if(i==n-1&&j==m-1) { //dfs结束条件
if(k_count==k) {
count = count % 1000000007;
count++;
}
return ;
}
for(int di=0;di<=1;di++) {
for(int dj=0;dj<=1;dj++) {
if(di+dj==1&&(i+di<n)&&(j+dj<m)) {//保证向右或者向下,并且没有超出数组
if(pandaun(i+di, j+dj,k_count,baowu)) {//如果判断出可以拿
dfs(i+di, j+dj, true,k_count,baowu); //进行dfs拿了当前宝物的情况
}
dfs(i+di, j+dj, false,k_count,baowu);//进行dfs没拿当前宝物的情况
}
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
m = scanner.nextInt();
k = scanner.nextInt();//k件宝物
data = new int[n][m];
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
data[i][j] = scanner.nextInt();
}
}
int[] baowu = new int[n*m];
dfs(0, 0,true,0,baowu);//拿了第一件宝物
dfs(0, 0,false,0,baowu);//没拿第一件宝物
System.out.println(count);
}
}