Click to view: Blue Bridge Cup title Studies Management Solutions Directory
Take the underground palace treasure
思路分析:
1. 写出递归框架,中间加上约束条件
2. if(i==m || j==n || count>k) 超过地宫边界,取出数目>k ,return 0;
3. if (i == m - 1 && j == n - 1) 到达递归的出口,再判断现有的宝贝数目
数目=k,情况数+1; 数目=k-1 并且最后一个宝物大于现有的所有宝物,取走,情况数+1;
4. 其余未达到k的情况 不做处理,下次循环 将超出地宫边界,return 0;
5. 对递归体: if(current>max) 则可以取出(count+1) 再向右或向下递归
也可以不取出,再向右和向下递归
if(current<=max) 只能不取出,再向右和向下递归
6. 对每步得到的 ans 对1000000007取模
7. 对记忆型递归而言: 在递归结尾 记录状态值
在递归开头,判断状态值是否被记录,若被记录直接 return 状态值,未被记录 执行递归。
package java_2014_B;
import java.util.Scanner;
public class Main009_地宫取宝 {
static int m,n,k;
static int[][] a;
static int [][][][]f = new int[51][51][14][14];
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
m = in.nextInt();
n = in.nextInt();
k = in.nextInt();
a = new int[m][n];
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
a[i][j]=in.nextInt(); // 初始化记忆型递归的数组
for(int i=0;i<51;i++)
for(int j=0;j<51;j++)
for(int l=0;l<14;l++)
for(int o=0;o<14;o++)
f[i][j][l][o]=-1;
long ans = dfs(0,0,-1,0);
System.out.println(ans);
}
private static long dfs(int i, int j, int max, int count) {
if(f[i][j][max+1][count] != -1) return f[i][j][max+1][count];
if(i==m || j==n || count>k) {
return 0;
}
int cur=a[i][j],ans=0;
if (i == m - 1 && j == n - 1) {
if (count == k || (count == k - 1 && cur > max))
return 1;
return 0;
}
if(cur>max) {
ans+=dfs(i, j+1, cur, count+1); // 取出当前的宝藏,向右走
ans%=1000000007;
ans+=dfs(i+1, j, cur, count+1); // 取出当前的宝藏,向下走
ans%=1000000007;
}
ans+=dfs(i, j+1, max, count); // 不取当前宝藏,向右走
ans%=1000000007;
ans+=dfs(i+1, j, max, count); // 不取当前宝藏,向下走
ans%=1000000007;
f[i][j][max+1][count]=ans%1000000007;
return ans;
}
}