1. 程式人生 > >演算法_記憶化搜尋DFS_地宮取寶

演算法_記憶化搜尋DFS_地宮取寶

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

package com.lulu.main9;


import java.util.Scanner;


public class Main {
static int n, m, k;//程式輸入值

        //為記憶化搜尋做標記,避免重複,已經知道有多少種方法就不用在計算了
static int [][][][] plan = new int [51][51][13][13];
static int [][] map;//所要走的地圖

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
k = in.nextInt();
map = new int[n][m];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
map[i][j] = in.nextInt();
}
}
for(int a = 0; a < 51; a++)
{
for(int b = 0; b < 51; b++)
{
for(int c = 0; c < 13; c++)
{
for(int d = 0; d < 13; d++)
{
plan[a][b][c][d] = -1;
}
}
}
}
plan[0][0][0][0] = bfs(0,0,0,-1);
System.out.println(plan[0][0][0][0]);
}


private static int bfs(int i, int j, int count, int max) {
if(plan[i][j][count][max+1]!=-1)
{
return plan[i][j][count][max+1];
}
int t = 0;
if(i == n-1 && j == m-1)
{
if(count == k || (count == k-1 && max < map[i][j])) t++;
return plan[i][j][count][max+1] = t;
}
if(i + 1 < n)
{
if(max < map[i][j])
t += bfs(i+1,j,count+1,map[i][j]);
t += bfs(i+1, j, count, max);
}
if(j + 1 < m)
{
if(max < map[i][j])
t += bfs(i, j+1, count+1, map[i][j]);
t += bfs(i, j+1, count, max);
}
t %= 1000000007;
return plan[i][j][count][max+1] = t;
}
}