一個有趣的迷宮題

首先,題目是這樣的:

標題:地宮取寶
    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);
}
}

結果無誤,如下圖:


代碼雖然有點長,但是比較容易理解(反正我是這樣認爲的。)



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