题目描述 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;
}