标题:地宫取宝
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 2 2
1 2
2 1
程序应该输出:
2
再例如,输入:
2 3 2
1 2 3
2 1 5
程序应该输出:
14
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
#include<stdio.h>
#define N 50
#define M 50
#define MaxSize 5000
typedef struct
{
int i,j;
int kk;//物品数量
int max;//最大的
}Box;
typedef struct
{
Box data[MaxSize];
int top;
}SqTack;//经典迷宫问题的结构体
SqTack sq;
int mg[N][M],num[50]={0},n,m,k,c=0,ys=1000000007;
void push(int i,int j,int kk,int max)//进栈
{
sq.top++;
sq.data[sq.top].i=i;
sq.data[sq.top].j=j;
sq.data[sq.top].kk=kk;
sq.data[sq.top].max=max;
}
int xdfa(int s)//用数组保存数
{
int i=0;
num[0]++;
while(i<=s)
{
if(num[i]>9)
{
num[i+1]+=num[i]/10;
num[i]=num[i]%10;
}
i++;
}
if(num[i]!=0)
return i;
else
return i-1;
}
int decre(int cc)//大数作减法
{
int ysz[10]={7,0,0,0,0,0,0,0,0,1},i;
for(i=0;i<cc;i++)
{
if(i<10)
num[i]=num[i]-ysz[i];
if(num[i]<0)
{
num[i]=10+num[i];
num[i+1]--;
}
}
if(num[cc]==0)
return cc-1;
else
return cc;
}
int toInt(int cc)//数组转为整数
{
int m=0;
while(cc>=0)
{
m=m*10+num[cc];
cc--;
}
return m;
}
void print(int cc)//cc表示的是数组最高位,cc+1表示的是数组中的有效位数
{
while(cc>9)
cc=decre(cc);
printf("%d\n",toInt(cc)%ys);
}
void quBao(int xi,int yi,int xe,int ye)
{
int i,j,max,kk=0,flag=0;
sq.top=-1;
sq.top++;
sq.data[sq.top].i=i=xi;
sq.data[sq.top].j=j=yi;
sq.data[sq.top].kk=0;
sq.data[sq.top].max=0;
max=mg[i][j];
kk++;
while(flag==0)
{
flag=1;
if(i==xe&&j==ye&&kk==k)
{
c=xdfa(c);
}
if(i==xe&&j==ye&&sq.top>-1)
{
i=sq.data[sq.top].i;
j=sq.data[sq.top].j;
max=sq.data[sq.top].max;
kk=sq.data[sq.top].kk;
sq.top--;
flag=0;
}
if(i+1<n&&j+1<m)
{
if(mg[i+1][j]>max)
{
push(i+1,j,kk,max);
push(i+1,j,kk+1,mg[i+1][j]);
}
else
push(i+1,j,kk,max);
if(mg[i][j+1]>max)
push(i,j+1,kk+1,mg[i][j+1]);
j=j+1;
flag=0;
}
else if(i+1<n)
{
if(mg[i+1][j]>max)
push(i+1,j,kk+1,mg[i+1][j]);
i=i+1;
flag=0;
}
else if(j+1<m)
{
if(mg[i][j+1]>max)
push(i,j+1,kk+1,mg[i][j+1]);
j=j+1;
flag=0;
}
}
}
int main()
{
int i,j;
scanf("%d%d%d",&n,&m,&k);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&mg[i][j]);
quBao(0,0,n-1,m-1);
print(c);
}