第一想法是dfs,发现超时,看了题解才发现是动态规划
dfs代码(无法AC)
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<queue>
using namespace std;
typedef long long ll;
int endx,endy,mx,my,mp[23][23];
int d1[] = {-1,-1,-2,-2,1,1,2,2};
int d2[] = {-2,2,-1,1,-2,2,-1,1};
int txy[] = {0,1,0},ans;
int vis[23][23];
void dfs(int x, int y)
{
if( x == endx && y == endy)
{
ans++;
return;
}
if(mp[x][y]==-1) return;
for(int i=0;i<=1;++i)
{
int tx = x + txy[i];
int ty = y + txy[i+1];
if( tx < 0 || tx > endx || ty < 0 || ty > endy || mp[tx][ty]==-1 || vis[tx][ty] ) continue; // -1不能走,被走过也不能走
vis[tx][ty] = 1;
dfs(tx,ty);
vis[tx][ty] = 0;
}
}
int main()
{
memset(mp,0,sizeof(mp)); //初始化为 0
scanf("%d %d %d %d",&endx,&endy,&mx,&my);
mp[mx][my] = -1; //有马不能走为-1
for(int i=0;i<=7;++i)
{
int tx = mx + d1[i];
int ty = my + d2[i];
if( tx>=0 && tx<=endx && ty>=0 && ty<=endy) mp[tx][ty] = -1;
}
vis[0][0] = 1;
dfs(0,0);
cout<<ans<<endl;
return 0;
}
AC代码
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<queue>
using namespace std;
typedef long long ll;
//dp[i][j] = dp[i-1][j] + dp[i][j-1] 状态转移方程
//dp[i][j]表示到达i,j这个点的路径条数
int endx,endy,mx,my;
ll dp[23][23];
bool vis[23][23];
int d1[] = {-1,-1,-2,-2,1,1,2,2};
int d2[] = {-2,2,-1,1,-2,2,-1,1};
int main()
{
//说下数组加2的原因:因为马往上跳数组会-2 ---> 超边界
cin>>endx>>endy>>mx>>my;
vis[mx+2][my+2] = 1;
dp[2][1] = 1;
for(int i=0;i<=7;++i)
{
int tx = mx + d1[i] + 2;
int ty = my + d2[i] + 2;
vis[tx][ty] = 1 ;
}
for(int i=2;i<=endx+2;++i)
{
for(int j=2;j<=endy+2;++j)
{
if(vis[i][j]) continue;
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
cout<<dp[endx+2][endy+2]<<endl;
return 0;
}