小乐乐下象棋(记忆化搜索)

链接:https://ac.nowcoder.com/acm/contest/301/F
来源:牛客网
 

小乐乐一天天就知道玩,这一天又想玩象棋。
我们都知道马走日。
现在给定一个棋盘,大小是n*m,把棋盘放在第一象限,棋盘的左下角是(0,0),右上角是(n - 1, m - 1);
小乐乐想知道,一个马从左下角(0, 0)开始,走了k步之后,刚好走到右上角(n - 1, m - 1)的方案数。

输入描述:

输入:多组样例输入,每组一行,三个整数n, m, k(1 <= n, m, k <= 200),如题目所示。

输出描述:

输出:输出答案 mod 1000000007

示例1

输入

复制

4 4 2

输出

复制

2
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int dir[8][2]={2,1,2,-1,1,2,1,-2,-2,-1,-2,1,-1,2,-1,-2};
int ei,ej;
const int mod=1e9+7;
const int maxn=2e2+10;
bool vis[maxn][maxn];
typedef long long ll; 
ll dp[maxn][maxn][maxn];
int n,m,k;
struct node
{
	int x,y,t;
	node(int x,int y,int t)
	{
		this->x=x;
		this->y=y;
		this->t=t;
	}
	node(){
	}
};

ll dfs(int x,int y,int k1)
{
	if(dp[x][y][k1]!=-1) return dp[x][y][k1];//dp这个可以解决大量时间,原来如此 ,记忆化搜索 
	if(k1==k)
	{
		if(x==ei&&y==ej) return 1;
		else return 0;
	}
	ll ans=0;
	for(int i=0;i<8;i++)
	{
		int xx=x+dir[i][0];
		int yy=y+dir[i][1];
		if(0<=xx&&xx<n&&0<=yy&&yy<m)
		{
			ans=(ans+dfs(xx,yy,k1+1))%mod;
		}
	}
	dp[x][y][k1]=ans;
	return ans;
}
int main()
{
	while(~scanf("%d%d%d",&n,&m,&k))
	{
		ei=n-1,ej=m-1;
		memset(dp,-1,sizeof(dp));
		printf("%lld\n",dfs(0,0,0)%mod);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/85301936