問題 1436: [藍橋杯][2014年第五屆真題]地宮取寶
時間限制: 1Sec 內存限制: 128MB 提交: 1329 解決: 329
題目描述
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
思路:
對於一個格子的物品,有2種選擇
第一種:可以拿它但是不拿它或者不能拿它 ->向右或者向下走,不拿
第二種:可以拿並拿了這個物品 ->拿
直接暴力深搜會超時,所有用數組記錄已經深搜過的轉態
代碼:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int n,m,k;
static int g[][]=new int[55][55];
static int dp[][][][]=new int[55][55][20][20];
static int dfs(int x,int y,int num,int big){
if(dp[x][y][num][big]!=-1) return dp[x][y][num][big];
dp[x][y][num][big]=0;
if(x==n && y==m && num==k) dp[x][y][num][big]=1;
if(num< k && g[x][y]>big){
dp[x][y][num][big]+=dfs(x,y,num+1,g[x][y]);
dp[x][y][num][big]%=1000000007;
}
if(x<n){
dp[x][y][num][big]+=dfs(x+1,y,num,big);
dp[x][y][num][big]%=1000000007;
}
if(y<m){
dp[x][y][num][big]+=dfs(x,y+1,num,big);
dp[x][y][num][big]%=1000000007;
}
return dp[x][y][num][big];
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
n=scan.nextInt();
m=scan.nextInt();
k=scan.nextInt();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
g[i][j]=scan.nextInt();
g[i][j]++;//避免0
}
for(int i=0;i<55;i++)
for(int j=0;j<55;j++)
for(int k=0;k<20;k++)
for(int t=0;t<20;t++)
dp[i][j][k][t]=-1;
dfs(1,1,0,0);
System.out.println(dp[1][1][0][0]);
}
}