hdu 1978 How many ways
题目传送门
解题思路:运用记忆化搜索,将终点的方案书设为 1,然后从七点开始搜,直到终点,在一步一步往回,最后得知最终方案数
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,k=1;char c=getchar();
while(c<'0' || c>'9'){if(c=='-') k=0;c=getchar();}
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return k?x:-x;
}
int T,n,m,a[110][110],mk[110][110];
int dfs(int x,int y)
{
if(mk[x][y]!=-1) return mk[x][y];//如果这个点已经有方案数了,那么直接返回这个点的值,省去一遍搜索
int s=0;//将计数器归 0
int tmp=a[x][y];//因为你在当前点你的能量为当前点的数值,所以用 tmp 记录下来
for(int i=0;i<=tmp;i++)//向右走 i 步,并且步数不能能超过当前能量
{
if(i+x>=n) break;//横坐标越界
for(int j=0;i+j<=tmp;j++)//向下走 j 步,并且 i+j 的总步数不能超过当前能量判断
{
if(j+y>=m) break;//纵坐标越界判断
if(i+j) s+=dfs(x+i,y+j);//如果 i+j不是 0 也就是没有原地不动,那么就把计数器加上dfs(下一个位置的方案数)
}
}
s%=10000;//方案数取余 10000
return mk[x][y]=s;//将当前点赋值为 s
}
int main()
{
T=read();//输入
while(T--)
{
n=read(),m=read();//输入
for(int i=0;i<n;i++) for(int j=0;j<m;j++) a[i][j]=read(),mk[i][j]=-1;
//输入以及初始化,一定要把 mk[i][j] 设为 -1 因为有些点的方案数有可能是 0
mk[n-1][m-1]=1;//因为是记忆化搜索,所以将终点的方案数设为 1,倒着搜
printf("%d\n",dfs(0,0));//记忆化搜索,从起点往终点搜,然后再返回来
}
return 0;
}