题目描述

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
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m[55][55];
int dp[55][55][15][15];    //用于记忆,是否出现过
int x,y,n;
int dfs(int a,int b,int c,int d)
{
    if(dp[a][b][c][d+1]!=-1)     //出现直接返回
        return dp[a][b][c][d+1];
    if(a==x-1&&b==y-1)
    {
        if(c==n||(c==n-1&&d<m[a][b]) )
		    return dp[a][b][c][d+1]=1;
        else
            return dp[a][b][c][d+1]=0;
    }
    long long int ww=0;
    if(a+1<x)       //向右
    {
        if(m[a][b]>d)
            ww+=dfs(a+1,b,c+1,m[a][b]);
        ww+=dfs(a+1,b,c,d);
    }
    if(b+1<y)      //向下
    {
        if(m[a][b]>d)
            ww+=dfs(a,b+1,c+1,m[a][b]);
        ww+=dfs(a,b+1,c,d);
    }
    dp[a][b][c][d+1]=ww%1000000007;
    return dp[a][b][c][d+1];
}
int main()
{
    int a,b,c,d,e;
    cin>>x>>y>>n;
    for(a=0;a<x;a++)
    {
        for(b=0;b<y;b++)
        {
            cin>>m[a][b];
        }
    }
    memset(dp,-1,sizeof(dp));
    b=dfs(0,0,0,-1);
    cout<<b<<endl;
}