^(* ̄(oo) ̄)^我在洛谷发过 咱们先设 𝑑𝑝𝑖,𝑗 表示第 𝑖 行 𝑗 列卒走到这里有多少种方式。
卒是可以向右或者向下走,所以到这个点只能从左或向上来,不难得出转移公式:𝑑𝑝𝑖,𝑗=𝑑𝑝𝑖−1,𝑗+𝑑𝑝𝑖,𝑗−1。
如果说马在这个点上或者说马能到这个点上,那么卒就不能到这个点,也就是卒到这个点的方式为0。
如何判断马能不能到这个点呢?所以我们需要一个方向数组,马能走八个方向,依次枚举这八个点是不是当前点就行了。
以上就是全部思路.
敲黑板!!! dp0,0 赋值为1初始化。 在转移过程中会数组越界,所以需要判断。 转移时如果当前点是 0,0则不进行转移,因为这是初始点,已经有值了。
ac代码(才怪)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int dp[25][25];
int dx[8]={-1,-2,-2,-1,1,2,2,1},dy[8]={-2,-1,1,2,2,1,-1,-2};
signed main(){
int n,m,x,y;
cin>>n>>m>>x>>y;
dp[0][0]=1;
bool ok=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(i==0&&j==0)continue;
ok=1;
if(i==x&&j==y)ok=0;
for(int k=0;k<8;k++){
if(i==x+dx[k]&&j==y+dy[k]){ok=0;break;}
}
if(ok){
if(i-1<0){
dp[i][j]=dp[i][j-1];
}
else if(j-1<0){
dp[i][j]=dp[i-1][j];
}
else{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
}
}
cout<<dp[n][m]<<endl;
return 0;
}