问题描述
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 取模的结果。
样例输入
2221221
样例输出
2
样例输入
232123215
样例输出
14
import java.util.Scanner;publicclass 地宫取宝 {staticint[][] a;staticint n,m,k;staticlong MOD=1000000007;staticint count=0;staticlong[][][][] visited=newlong[51][51][13][13];//在(n,m)这个点的时候手中拥有x个宝物,最大价值为mpublicstaticlongdfs(int x,int y,int num,int max){if(visited[x][y][num][max+1]!=-1)//不在出发点的时候return visited[x][y][num][max+1];//而max要作为数组下标,显然最小为0,故初始化为-1,然后都+1就解决了,其实max+1就是当前状态 if(x==n-1&&y==m-1){如果到达终点 if(num==k||(num==k-1&&max<a[x][y]))//如果手中有k个宝物就不拿重点的宝物
visited[x][y][num][max+1]=1;//赋值为1//而此时终点的宝物价值大于max,便拿起终点的宝物(对终点宝物的拿与不拿) else
visited[x][y][num][max+1]=0;//不拿return visited[x][y][num][max+1];}long result=0;if(x+1<n){//向下移动一步if(max<a[x][y]){//如果手中的东西比不上下面的宝物价值
result +=dfs(x+1,y,num+1,a[x][y]);
result %= MOD;}
result +=dfs(x+1,y,num,max);//往下面走
result %= MOD;}if(y+1<m){//向右移动if(max<a[x][y]){
result +=dfs(x,y+1,num+1,a[x][y]);
result %=MOD;}
result +=dfs(x,y+1,num,max);
result %=MOD;}return visited[x][y][num][max+1]=result%MOD;}publicstaticvoidmain(String[] args){// TODO Auto-generated method stub
Scanner sc=newScanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
k=sc.nextInt();
a =newint[n][m];int bmax=-1;for(int i=0;i<n;i++){for(int j=0;j<m;j++){
a[i][j]=sc.nextInt();}}//好像必须要初始化,我把他去掉了之后就不对了。for(int i=0;i<51;i++){//n,m最大只能50for(int j=0;j<51;j++){for(int x=0;x<13;x++){for(int y=0;y<13;y++)
visited[i][j][x][y]=-1;//初始化应该为-1,应为开始的时候啥也不取得时候}}}dfs(0,0,0,-1);//在(0,0)这个点,有0个宝物,最大价值为-1
System.out.println(visited[0][0][0][0]);}}