这个道题应该可以作为dp的入门题目吧,虽然推出来的方程像递推式,思想才最重要的。
题目说卒子只能向下和向右走,但是有些地方不能走,让我们求可以到达终点的路径数。
有的同学会问dfs不就行了嘛,这题的数据小dfs当然可以,只不过太费时,dp大法好呀。
我们先来推一下方程式,我们假定要找起点到(6,6)的路径数,那么,我们找出(5,6)和(6,5)的路径数不就行了嘛,他们的和不就是(6,6)的路径数嘛,通过假设,我们就可以得到方程式了,就是dp[i][j]=dp[i-1][j]+dp[i][j-1]。接下来的话我们直接写就行了。
需要注意的三点!!!
一.注意一下就是数组越界(马走日)。
二.再就是初始dp的值,没有马的干扰的话,我们第0行上的初始值应该都是为1的,因为只有一种走法,但是有了比如(0,4)不能走,那么从第四列起,包括第四列以后的值应该为0,因为没法向上走,也穿不了障碍,第0行0-3列的值则为1。
三.最后就是由于路径可能很多,我们得讲dp开到longlong,不然可能会有测试点WA哦
到这里的话,就没有什么坑能阻止我们ac了
#include<bits/stdc++.h>
using namespace std;
int mp[25][25];
long long dp[25][25];
int n,m;
inline void f(int x,int y){
mp[x][y]=1;
if(x-2>=0&&y-1>=0){
mp[x-2][y-1]=1;
}
if(x-1>=0&&y-2>=0){
mp[x-1][y-2]=1;
}
if(x+2<=n&&y-1>=0){
mp[x+2][y-1]=1;
}
if(x+1<=n&&y-2>=0){
mp[x+1][y-2]=1;
}
if(x+1<=n&&y+2<=m){
mp[x+1][y+2]=1;
}
if(x+2<=n&&y+1<=m){
mp[x+2][y+1]=1;
}
if(x-2>=0&&y+1<=m){
mp[x-2][y+1]=1;
}
if(x-1>=0&&y+2<=m){
mp[x-1][y+2]=1;
}
}
int main(){
int x,y;
scanf("%d%d%d%d",&n,&m,&x,&y);
f(x,y);
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(!mp[i][j]){
if(i==0&&j==0){
dp[0][0]=1;
}
else if(i==0&&j>0){
dp[i][j]=dp[i][j-1];
}
else if(j==0&&i>0){
dp[i][j]=dp[i-1][j];
}
else{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
else{
dp[i][j]=0;
}
}
}
printf("%lld",dp[n][m]);
return 0;
}