1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| import java.util.Scanner;
/* * 修改后的递归 */ public class Main {
static int n,m,k; static int[][] map; static long[][][][] data; public static void main(String[] args) { Scanner sc=new Scanner(System.in); n=sc.nextInt(); m=sc.nextInt(); k=sc.nextInt(); map=new int[n+2][m+2]; data=new long[52][52][14][14]; for(int i=0;i<52;i++){ for(int ii=0;ii<52;ii++){ for(int iii=0;iii<14;iii++){ for(int iiii=0;iiii<14;iiii++){ data[i][ii][iii][iiii]=-1; } } } } for (int i = 0; i < n+2; i++) { for (int j = 0; j < m+2; j++) { if(i==0||j==0||i==n+1||j==m+1)//加一道墙 map[i][j]=-1; else map[i][j]=sc.nextInt(); } } long total = dfs(1,1,-1,k); //从(1,1)开始,还可以拿k个,现在可拿">-1"的值 //这里写dfs(1,1,0,k)效果是一样的,为防止map中有质量为0的物品,写-1更稳妥 System.out.println(total%1000000007); } //max当前拿到手中的最大个,count还可以拿多少个 private static long dfs(int i, int j,int max,int count) { //System.out.println("("+i+","+j+"),count="+count+",max="+max); //无意义 if(!check(i, j, count)){ return 0; } //到达 if(i==n && j==m && count==0){ //System.out.println("成功!"); return data[i][j][max+1][count]=1; } if(i==n && j==m && count==1 && map[i][j]>max){ //System.out.println("成功!取最后一个"); return data[i][j][max+1][count]=1; } if(data[i][j][max+1][count]!=-1){ return data[i][j][max+1][count]; } //如果现在的可以拿,则有四种情况:拿起,向右走;拿起,向下走;不拿,向右走;不拿向下走。 if(map[i][j]>max){ data[i][j][max+1][count]=dfs(i,j+1,map[i][j],count-1)+dfs(i+1,j,map[i][j],count-1)+dfs(i,j+1,max,count)+dfs(i+1,j,max,count); return data[i][j][max+1][count]; } //如果现在的不能拿,则有两种情况:不拿,向右走;不拿向下走。 if(map[i][j]<=max){ data[i][j][max+1][count]=dfs(i+1,j,max,count)+dfs(i,j+1,max,count); return data[i][j][max+1][count]; } return 0; }
private static boolean check(int i, int j, int count) { if(map[i][j]!=-1 && count>=0) return true; else return false; } }
|