洛谷 P1002 过河卒

传送门

思路

菜鸡小学生\(loceaner\)现在才知道过河卒怎么做……

首先我们把马的控制点全部标记一下(顺便判断一下边界,后面就不用判了)

然后用\(DP\)来做,需要注意的是如果\(f[0][0]\)也是妈的控制点的话,就没法到达\(B\)点了,所以\((0,0)\)不是控制点才可以到达,且到达此点的方式只有一种,在代码中便是这一句if(!f[0][0]) dp[0][0] = 1;

之后便是\(DP\)过程了,循环过程中,如果当前点是马的控制点,则直接跳过,如果不是,只要\(i\)大于\(0\),便可以由\(dp[i-1][j]\)转化过来,只要\(j\)大于\(0\),就可以从\(dp[i][j - 1]\)转化过来,总体转移方程为

\[ \begin{equation} dp[i][j] = dp[i][j] + \begin{cases} dp[i - 1][j] (i > 0)\\ dp[i][j-1](j >0)\\ \end{cases} \end{equation} \]

最后的答案显然在\(dp[bx][by]\)

代码

#include <cstdio>
#include <iostream>
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

int mx, my, bx, by;
long long dp[21][21];
bool f[21][21];

void pre(int i, int j) {
    if(i >= 0 && i <= bx && j >= 0 && j <= by)
        f[i][j] = true;
    return;
}

int main() {
    bx = read(), by = read(), mx = read(), my  = read();
    pre(mx, my);
    pre(mx - 2, my + 1);
    pre(mx - 2, my - 1);
    pre(mx - 1, my + 2);
    pre(mx - 1, my - 2);
    pre(mx + 1, my + 2);
    pre(mx + 1, my - 2);
    pre(mx + 2, my - 1);
    pre(mx + 2, my + 1);
    if(!f[0][0])dp[0][0] = 1;
    for(int i = 0; i <= bx; i++) {
        for(int j = 0; j <= by; j++) {
            if(f[i][j]) continue;
            if(i > 0) dp[i][j] += dp[i - 1][j];
            if(j > 0) dp[i][j] += dp[i][j - 1];
        }
    }
    cout << dp[bx][by] << '\n';
    return 0;
}

转载于:https://www.cnblogs.com/loceaner/p/11448388.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值