洛谷 P1002 过河卒(dp)

虽然是一道简单题,但也花了比较长时间。。(比较怕负数。。)
题目链接:https://www.luogu.org/problemnew/show/P1002
题目描述
棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的。

现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入输出格式
输入格式:
一行四个数据,分别表示B点坐标和马的坐标。

输出格式
一个数据,表示所有的路径条数。

输入输出样例
输入样例#1:

6 6 3 3

输出样例#1:

6

注意点:
1.题目数据比较大,用long long
2.如果和我一样怕负数的话。。就在输入后全都加一吧。。
代码如下:

#include 
#include 
#include 
#define ll long long
using namespace std;
ll dp[50][50],ma_x,ma_y,Bx,By;
int flag[30][30]={0};
int a[12]={0,-1,-2,-2,-1,1,2,2,1,0};
int b[12]={0,2,1,-1,-2,-2,-1,1,2,0};
int main(){
    scanf("%lld %lld %lld %lld",&Bx,&By,&ma_x,&ma_y);//B为终点,ma为马的位置。
    Bx++;By++;ma_x++;ma_y++;//怂。。+1
    for(int i=1;i<=9;i++){
        if(ma_x+a[i]>=0&&ma_y+b[i]>=0)
            flag[ma_x+a[i]][ma_y+b[i]]=1;
    }
    dp[1][1]=1;//初始化
    for(int i=1;i<=Bx;i++){
        for(int j=1;j<=By;j++){
            if(flag[i][j])//被马控制的点跳过
                continue;
            if(i==1&&j==1)
                continue;
            dp[i][j]=dp[i-1][j]+dp[i][j-1];//状态转移方程
        }
    }
    printf("%lld\n",dp[Bx][By]);
return 0;
}

总结,dp题目还是要多加练习。羡慕大佬们哪个题目没见过。

你可能感兴趣的:(DP)