【洛谷】【动态规划】P1002 [NOIP2002 普及组] 过河卒

题目链接:https://www.luogu.com.cn/problem/P1002

题目描述

  棋盘上 A点有一个过河卒,需要走到目标 B点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

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

img

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

输入格式

  一行四个正整数,分别表示 B点坐标和马的坐标。

输出格式

  一个整数,表示所有的路径条数。

测试样例

输入
6 6 3 3
输出
6

解题思路

1.首先我们要明白,哪些点是马可以走到的点,我们针对这个题为例,A为原点,B为目标点,X为马可以走到的点

 A 0 0 0 0 0 0
 0 0 X 0 X 0 0
 0 X 0 0 0 X 0
 0 0 0 M 0 0 0
 0 X 0 0 0 X 0
 0 0 X 0 X 0 0
 0 0 0 0 0 0 B

2.在这里我们发现,马的行动范围在[2,2]以内,如果我们直接用状态转移的话,在i-1和j-1的时候就会发生数组越界,所以我们在这里选择的是把所有点的坐标统一加2

3.在计算路径时,我们发现,A只能向右走或者向下走,所以对于每一个点,只需要计算从它左边和上边来的路径之和即可,这就是本题的状态转移方程,如下所示
f [ i ] [ j ] = m a x ( f [ i ] [ j − 1 ] + f [ i − 1 ] [ j ] , f [ i ] [ j ] ) f[i][j] = max( f[i][j-1] + f[i-1][j] , f[i][j] ) f[i][j]=max(f[i][j1]+f[i1][j],f[i][j])
针对本题计算出来的结果如下所示

1 1 1 1 1 1 1
1 0 X 1 X 1 2
1 X 0 1 1 X 2
1 1 1 M 1 1 3
1 X 1 1 0 X 3
1 1 X 1 X 0 3
1 2 2 3 3 3 6

AC代码

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int bx,by,mx,my;
    cin>>bx>>by>>mx>>my;
    //加2避免马的影响
    bx+=2; by+=2;
    mx+=2; my+=2;
    //这里一定记得是long long,要不然会WA的!
    long long area[30][30]={0};
    bool ma[30][30]={0};
    int x[]={0,-2,-1,1,2,-2,-1,1,2};
    int y[]={0,1,2,2,1,-1,-2,-2,-1};
    //把马能走的位置设为1,后续方便判断
    for(int i=0;i<9;i++)
    {
        ma[mx+x[i]][my+y[i]] = 1;
    }

    area[2][2] = 1;
    //开始dp
    for(int i=2;i<=bx;i++)
    {
        for(int j=2;j<=by;j++)
        {
            if(ma[i][j]) continue;
            //状态转移方程
            else area[i][j] = max(area[i][j-1] + area[i-1][j],area[i][j]);
        }
    }
    //输出结果
    cout<<area[bx][by];
    return 0;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 这是一道描述棋盘上走棋规则的问题。给出了三个点aa、bb、cc,要求从aa点到bb点走一步,需要沿下方向或者向右方向走。同时,在棋盘上有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此,需要注意能够到达bb点的点必须不在对方马的控制点上。这个问题称为“马拦”。 ### 回答2: 这道题类似于迷宫探索。我们可以把棋盘看成一个坐标系,的位置为起点,目标点为终点。既然只能向下或向右移动,那么我们只需要让向着目标点最短的方向移动,直到到达目标点即可。 但是,这道题的难点在于对方的马。因为马能够控制到的点都是对的威胁,所以我们需要先判断对方马能否对造成威胁。如果对方马距离的横向距离大于等于3,纵向距离大于等于3,则该马无法将拦截,可以直接行走。如果对方马距离的横向距离小于2,纵向距离小于2,则该马直接将拦截。如果对方马距离的横向距离等于2,纵向距离等于2,则需要根据对方马的具体位置进行判断。 如果对方马距离的横向距离等于2,纵向距离等于2,可以划分成四个方向判断。以对方马的位置为中心,向四个方向分别判断对应的点是否存在,如果存在则需要判断对方马是否能够到达该点,如果能够到达,则该点受到对方马的威胁。 如果能够避开对方马的威胁,就可以按照最短路径向目标点靠近。如果不能避开对方马的威胁,就需要考虑如何绕路。可以考虑分别向上和向左走一步,检查两个新点是否受到对方马的威胁,如果有威胁则需要再次绕路,直到找到安全的路径。 总之,在这种情况下,我们需要通过细致的分析来找出最优解决方案,保证能够安全到达目标点。 ### 回答3: 过是中国象棋中的一种棋子,只能向前走,且要过后才能横着走。现在有一个过需要走到目标点,但是在棋盘上还有一个对方的马,要阻止过的前进。 首先,我们需要了解棋盘的基本结构,其实就是一个8*8的方格棋盘。每个象棋棋子的行走路线都有它们自己的规则和限制。过可以向下或向右走,但是不能向上或者向左走。所以我们需要根据这个规则来寻找到达目标点的最短路径。 而对方的马则是另一个挑战。马的行走路线是一个“日”字形。当它的位置在过前进的路径上或者可以跳到过的行进路线上时,过就会被拦住。因此,我们需要绕过对方的马,选择路径避开对方马的控制点。 面对这个问题,我们可以通过回溯算法来解决。回溯算法是一种广泛使用的算法,可以用来寻找所有有效的路径。我们可以从起点开始,每次尝试向下或向右移动一步,同时检查是否到达了目标点,并考虑到对方马的控制点会对路径产生影响。如果被对方马拦住,我们需要绕路避开控制点,然后继续前进。最终,当找到一条到达目标点的有效路径时,就可以停止搜索。 总之,找到过到目标点的最短路径并绕开对方马的控制点是一个有挑战性的问题,但通过回溯算法,我们可以找到所有的有效路径,并且选出最短路径来解决这个问题。再复杂的问题,只要用正确的方法,都可以被解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小天才才

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值