鏈接: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<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f
#define ll long long
#define Mod 1000000007
int n,m,k;
ll ans;
int dir[8][2]={1,2,-1,2,1,-2,-1,-2,2,1,-2,1,2,-1,-2,-1};
ll dp[205][205][205];
ll dfs(int x,int y,int t)
{
if(dp[x][y][t]!=-1)
return dp[x][y][t];
ll ans=0;int tx,ty;
for(int i=0;i<8;i++)
{
tx=x+dir[i][0];
ty=y+dir[i][1];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&t<k)
{
ans=(ans+dfs(tx,ty,t+1))%Mod;
}
}
return dp[x][y][t]=ans;
}
int main()
{
while(scanf("%d %d %d",&n,&m,&k)!=EOF)
{
memset(dp,-1,sizeof(dp));
dp[n-1][m-1][k]=1;
printf("%lld\n",dfs(0,0,0));
}
return 0;
}