Loading

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;
}

posted @ 2020-02-02 22:34  ForeverOIer  阅读(105)  评论(0编辑  收藏  举报