题目描述 Description
设有一个n*m的棋盘(2≤n≤50,2≤m≤50),如下图,在棋盘上有一个中国象棋马。
规定:
1)马只能走日字
2)马只能向右跳
问给定起点x1,y1和终点x2,y2,求出马从x1,y1出发到x2,y2的合法路径条数。

输入描述 Input Description
第一行2个整数n和m
第二行4个整数x1,y1,x2,y2
输出描述 Output Description
输出方案数
样例输入 Sample Input
30 30
1 15 3 15
样例输出 Sample Output
2
数据范围及提示 Data Size & Hint
2<=n,m<=50
这是一个棋盘型DP题目,对于这种题目,我们只要找到其动态转移方程即可。另外需要注意的是对于这种问题,dfs会严重超时,不能使用,对数组定义类型的时候优先定义long类型,保证数据的范围。
动态转移方程:
(j + 1 <= m && i - 2 >= 1) dp[i][j] += dp[i - 2][j + 1];
(j + 2 <= m) dp[i][j] += dp[i - 1][j + 2];
(j - 1 >= 1 && i - 2 >= 1) dp[i][j] += dp[i - 2][j - 1];
(j - 2 >= 1) dp[i][j] += dp[i - 1][j - 2];
(j + 2 <= m) dp[i][j] += dp[i - 1][j + 2];
(j - 1 >= 1 && i - 2 >= 1) dp[i][j] += dp[i - 2][j - 1];
(j - 2 >= 1) dp[i][j] += dp[i - 1][j - 2];
代码如下:
/************************************************************************* > File Name: 骑士游历.cpp > Author: zhanghaoran > Mail: chilumanxi@gmail.com > Created Time: 2015年07月02日 星期四 13时57分30秒 ************************************************************************/ #include <iostream> #include <algorithm> #include <cstring> using namespace std; int n, m; int x1, x2, y1, y2; long dp[51][51]; int main(void){ cin >> n >> m; cin >> x1 >> y1 >> x2 >> y2; memset(dp, 0, sizeof(dp)); dp[x1][y1] = 1; for(int i = x1 + 1; i <= x2; i ++){ for(int j = 1; j <= m; j ++){ if(j + 1 <= m && i - 2 >= 1) dp[i][j] += dp[i - 2][j + 1]; if(j + 2 <= m) dp[i][j] += dp[i - 1][j + 2]; if(j - 1 >= 1 && i - 2 >= 1) dp[i][j] += dp[i - 2][j - 1]; if(j - 2 >= 1) dp[i][j] += dp[i - 1][j - 2]; } } cout << dp[x2][y2] << endl; return 0; }