题目 : 过河卒
题目分析
一道模板题,线性DP 但是要注意边界问题以及初始化的问题
-
我们可以用f(i,j) 表示 从A(0,0)到(i,j)该点的所有路线数
于是我们写出状态转移方程f[i][j] = f[i-1][j] + f[i][j-1] -
不难发现如果下标从0开始,i-1或j-1就会越界,所以我们不妨将数组从1开始
-
对于马的坐标我们可以用偏移量求,但是不难发现马的坐标会出现-2,所以我们就必须要把坐标轴偏移2,不然就会越界,还有就是马本身这个坐标也是要考虑
-
还有一个问题就是答案可能很大,所以我们得开long long
#include<iostream>
using namespace std;
const int N = 30;
typedef long long LL;
LL f[N][N];
bool st[N][N]; // 判别马的坐标
int n,m,hx,hy;
const int dx[] = {-2,-1,1,2,2,1,-1,-2};
const int dy[] = {1,2,2,1,-1,-2,-2,-1};
int main(){
cin>>n>>m>>hx>>hy;
// 由于马的坐标会用到-1或-2就会数组越界所以把棋盘偏移
n+=2,m+=2,hx+=2,hy+=2;
for(int i = 0; i < 8; i ++) st[dx[i]+hx][dy[i]+hy] = true;
//初始条件
//如果没有这个条件 f[1][1] = f[0][1] + f[1][0] = 0 了
f[1][2] = 1;
// 马自身也是一个点
st[hx][hy] = true;
// 下标从1开始防止越界,由于马的坐标可能会用到-2所以从2开始
for(int i = 2; i <= n; i ++)
for(int j = 2; j <= m; j ++){
if(st[i][j]) continue;
f[i][j] = f[i-1][j] + f[i][j-1];
}
cout<<f[n][m]<<endl;
return 0;
}