【题解】P1002 过河卒
题面
前言
我嘞个诈骗图片啊
云落以为是象棋棋盘大小,没曾想 \(n,m \le 20\)
正文
显然有 DP 直接做
转移方程形如 \(f_{i,j} = f_{i-1,j} + f_{i,j-1}\)
注意一些小细节:
比如说禁入点可能越界,所以需要 inbound
函数判断一下
再比如说题意要求是从 \((0,0)\) 到 \((n,m)\)(云落将其转化为从 \((1,1)\) 到 \((n+1,m+1)\))
时间复杂度 \(O(n \times m)\)
代码
#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int maxn=32;
const int dx[]={0,1,2,2,1,-1,-2,-2,-1};
const int dy[]={0,2,1,-1,-2,-2,-1,1,2};
int f[maxn][maxn];
int n,m,wx,wy;
inline bool inbound(int x,int y){
return x>=1&&x<=n&&y>=1&&y<=m;
}
signed main(){
cin>>n>>m>>wx>>wy;
n++;
m++;
wx++;
wy++;
memset(f,0,sizeof(f));
for(int i=0;i<9;i++){
int nx=wx+dx[i],ny=wy+dy[i];
if(inbound(nx,ny)){
f[nx][ny]=-1;
}
}
f[1][1]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1&&j==1){
continue;
}
if(f[i][j]==-1){
f[i][j]=0;
continue;
}
f[i][j]=f[i-1][j]+f[i][j-1];
}
}
cout<<f[n][m]<<endl;
return 0;
}
后记
难绷,一道橙题调了云落两个点……
完结撒花!