一个有趣的迷宫题

首先,题目是这样的:

标题:地宫取宝
    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 2 2
1 2
2 1
程序应该输出:
2

再例如,输入:
2 3 2
1 2 3
2 1 5
程序应该输出:
14

这是一个很老的题目了,但我在网上找了一下这个题的解法,基本都是用4维数组来解决问题的,今天,我就用二维数组来讲解一下这个题目。


首先,主函数是这样的

import java.util.Scanner;
public class test_nine {
public static void main(String[] args) {

Space s = new Space();
Scanner scanner = new Scanner(System.in);
s.nlen = scanner.nextInt(); //输入数组的长度
s.mlen = scanner.nextInt(); //输入数组的宽度
s.k = scanner.nextInt(); //输入恰好得到宝物数量

int a[][] = new int[s.nlen][s.mlen]; //存放迷宫
int karr[] = new int[s.nlen+s.mlen-1]; //存放路径上所有宝物
int t[] = new int[s.k]; //存放可行性宝物

for (int i = 0; i < s.nlen; i++) { //对迷宫进行输入赋值
for (int j = 0; j < s.mlen; j++) {
a[i][j] = scanner.nextInt();
}
}

s.space(0,0,0,karr,a,t); //从0行0列开始   此时手中宝贝数为0
s.display(); //输入方法总数
}
}

class Space{
int mlen , nlen , k; //迷宫的长度  宽度 恰好捡宝贝个数 
int count = 0; //记录方法总数
void space(int n, int m, int kcount,int karr[],int a[][],int t[]){
if (n == nlen || (n < nlen-1 && m == mlen)) { //越界返回
return;
}
if (n == nlen-1  && m == mlen ) {  //到达出口
combination(0, k, t ,karr ); //从0号元素开始取‘k’个数
return;
}
karr[kcount] = a[n][m]; //将当前格子的宝物放入数组
space(n+1, m, kcount+1, karr, a, t); //往下走进行递归
space(n, m+1, kcount+1, karr, a, t); //往右走进行递归
}

void combination(int low, int num,int t[],int karr[]){
if (num == 0) {
boolean b = true; //判断所取组合是否符合题目要求,即组合中元素是有序的,是则记录,否则跳回
for (int i = 0; i < t.length - 1 ; i++) {
if (t[i] <= t[i+1]) {
b = false;
}
}
if (b) {
count++;
}
}else {
for (int i = low; i < nlen+mlen-1; i++){ //进行组合运算(不懂的可以看看排列组合算法)
t[num-1] = karr[i];   
combination(i + 1, num - 1, t, karr);  
}
}
}

void display(){
System.out.println(count);
}
}

结果无误,如下图:


代码虽然有点长,但是比较容易理解(反正我是这样认为的。)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章