题目描述
棋盘上AAA点有一个过河卒,需要走到目标BBB点。卒行走的规则:可以向下、或者向右。同时在棋盘上CCC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,AAA点(0,0)(0, 0)(0,0)、BBB点(n,m)(n, m)(n,m)(nnn, mmm为不超过202020的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从AAA点能够到达BBB点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式:
一行四个数据,分别表示BBB点坐标和马的坐标。
输出格式:
一个数据,表示所有的路径条数。
输入输出样例:
输入样例#1: |
|
输出样例#1 |
|
思路:
因为转移方程的时候需要 i-1 和 j−1 所以如果不从 f[1][1] 开始就会因数组越界而 WA
从 f[1][1]开始就是把每个点的坐标都向右下角移动一个
f[1][1]=1
状态转移方程为f[i][j]=max(f[i−1][j]+f[i][j−1],f[i][j])
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int fx[]={0,-2,-1,1,2,2,1,-1,-2};
int fy[]={0,1,2,2,1,-1,-2,-2,-1};
int bx,by,mx,my;
ll ans;
ll f[30][30];
bool s[30][30];
int main(){
scanf("%d%d%d%d",&bx,&by,&mx,&my);
++bx; ++by; ++mx; ++my;//坐标+1以防越界
f[1][1]=1;//初始化
s[mx][my]=1;//标记马的位置
for(int i=1;i<=8;i++)
s[ mx + fx[i] ][ my + fy[i] ]=1;
for(int i=1;i<=bx;i++){
for(int j=1;j<=by;j++){
if(s[i][j])continue;
f[i][j]=max( f[i][j] , f[i-1][j] + f[i][j-1] ); //状态转移方程
}
}
printf("%ll\n",f[bx][by]);
return 0;
}