主要考察:动态规划(dp)
思路
一到很简单的动态规划题
首先要处理“马”,只需要在马所在的坐标和其能移动的八个点位标记即可,也就是这样的:
const int dir[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}}; d[cx][cy]=true; for(int i=0;i<8;i++){ int tx=cx+dir[i][0],ty=cy+dir[i][1];//移动 if(tx >= 0 && tx <= n && ty >= 0 && ty <= m)//如果在边界内 d[tx][ty]=true;//标记 }
然后讨论移动,我们可以发现,点只能由
和
移动得到,而到这个点的方案数便是
。得出状态转移方程
,由于到原点的方向只有一种,所以
,再处理一下边界就可以了
for(int i = 0;i <= n;i ++){ for(int j = 0;j <= m;j ++){ if(d[i][j] == false){//如果没被标记 if(i)//判边界 dp[i][j]+=dp[i-1][j];//转移 if(j)//判边界 dp[i][j]+=dp[i][j-1];//转移 } } }
AC代码
#include<bits/stdc++.h> using namespace std; const int dir[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}}; bool d[30][30]; long long dp[30][30],n,m,cx,cy; int main(){ cin>>n>>m>>cx>>cy; d[cx][cy] = true; for(int i = 0;i < 8;i ++){ int tx = cx + dir[i][0],ty = cy + dir[i][1]; if(tx >= 0 && tx <= n && ty >= 0 && ty <= m) d[tx][ty]=true; } dp[0][0]=1; for(int i = 0;i <= n;i ++){ for(int j = 0;j <= m;j ++){ if(d[i][j] == false){ if(i) dp[i][j]+=dp[i-1][j]; if(j) dp[i][j]+=dp[i][j-1]; } } } cout<<dp[n][m]<<endl; return 0; }