洛谷 P1002 过河卒

原创 2017年01月04日 00:21:13

题目描述

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

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

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:
6 6 3 3

输出样例#1:
6

解题思路

这题可以自己在草稿纸上数一下,到一个点到底有几种方法,然后归纳一下,即可得到:到达(x,y)的方法数等于到达(x-1,y)的方法数+到达(x,y-1)的方法数,然后不能去的地方特判一下,设成0,还有最左边一列和最上边一行特殊处理一下(见下),然后就没有然后了。
(粘一个烂大街但又很好懂的解析)对本题稍加分析就能发现,到达棋盘上的一个点,只能从左边过来(我们称之为左点)或是从上面过来(我们称之为上点)。根据加法原理,到达某一点的路径条数,就等于到达其相邻的上点或左点的路径数目总和。因此我们可以使用逐列(逐行)递推的方法来求出从起点到终点的路径数目。障碍点(马的控制点)也完全适用,只要将到达该点的路径数目设置为0即可。
假设用F[I,J]到达点(I,J)的路径数目用G[I,J]表示点(I,J)是否为对方马的控制点,G[I,J]=0表示不是对放马的控制点,G[I,J]=1表示是对方马的控制点。则,我们可以得到如下的递推关系式:
F[I,J]=0{G[I,J]=1}
F[I,0]=F[I-1,0]{I>0,G[I,0]=0}
F[0,J]=F[0,J-1]{J>0,G[0,J]=0}
F[I,J]=F[I-1,J]+F[I,J-1]{I>0,J>0,G[I,J]=0}
上述递推式边界是:F[0,0]:=1。考虑到最大情况下:n=20,m=20,路径条数可能会出现超出长整型范围,所以要用int64或comp类型计数或者高精度运算(是不是要开一个三维数组呢)。

#include<stdio.h>//这个编辑器的缩进比较怪异
short g[25][25];
int main()
{
    long long bn,bm,n,m;
    long long f[25][25];
    scanf("%lld%lld%lld%lld",&bn,&bm,&n,&m);
    for(int i=0;i<25;i++)
        for(int j=0;j<25;j++)
            g[i][j]=f[i][j]=0;
    f[0][0]=g[n][m]=1;
    if(n>=1&&m>=2) g[n-1][m-2]=1;
    if(n>=2&&m>=1) g[n-2][m-1]=1;
    if(n>=1) g[n-1][m+2]=1;
    if(n>=2) g[n-2][m+1]=1;
    if(m>=2) g[n+1][m-2]=1;
    if(m>=1) g[n+2][m-1]=1;//这一排if是针对数组越界的,还可以把整个棋盘全体下移再右移两格
    g[n+1][m+2]=1;
    g[n+2][m+1]=1;
    for(int i=1;i<25;i++)
    {
        if(!g[i][0])f[i][0]=f[i-1][0];
        if(!g[0][i])f[0][i]=f[0][i-1];
    }//边界如果为零,那它后面的都不可到达,我傻傻的把后面的照样赋值为1,0~60分不等
    
    for(int i=1;i<=bn;i++)
    {
        //printf("%6lld (%d %d)  ",f[i][0],i,0);
        for(int j=1;j<=bm;j++)
        {
            if(g[i][j])
                f[i][j]=0;
            else
                f[i][j]=f[i-1][j]+f[i][j-1];
            //printf("%6lld (%d %d)  ",f[i][j],i,j);
        }
        //printf("\n");
    }
    printf("%lld",f[bn][bm]);
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载

洛谷 P1002 过河卒

题目描述 棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。...
  • wawcac
  • wawcac
  • 2017年01月04日 00:21
  • 209

【Algothrim】动态规划实例(马拦过河卒)

[问题描述]:   如图,A 点有一个过河卒,需要走到目标B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制...
  • carol123456
  • carol123456
  • 2016年08月05日 17:18
  • 532

P1002过河卒

提供几组测试数据吧 8 7 3 2 102 14 16 4 5 10560723 20 20 10 10 21388094780 20 20 4 0 56477364570 首先想到的是从终点开...
  • qq_36326947
  • qq_36326947
  • 2017年03月22日 22:28
  • 2518

洛谷[P1002]过河卒 动态规划

我居然对着动规调了半天dfs...
  • WADuan2
  • WADuan2
  • 2016年08月12日 14:42
  • 1159

洛谷 P1052 过河

动态规划
  • Rlt1296
  • Rlt1296
  • 2016年07月31日 14:03
  • 318

SDAU训练日志第11篇----------动态规划(7)(2018年2月8日)

  • u011590573
  • u011590573
  • 2018年02月09日 00:00
  • 15

洛谷 p1002 过河卒

题目描述 棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒...
  • ye_xingyu
  • ye_xingyu
  • 2017年10月04日 18:44
  • 90

洛谷P1002 过河卒

貌似是我做的第一道dp题,hh岁月如水,很简单就不说啥了#include long long step[25][25]; bool map[25][25]; int main(){ int ...
  • Myriad_Dreamin
  • Myriad_Dreamin
  • 2017年12月30日 22:52
  • 27

【搜索】洛谷 P1002 过河卒

题目描述棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。棋盘...
  • hyj542682306
  • hyj542682306
  • 2017年04月24日 16:28
  • 312

洛谷 过河卒 p1002 题解

其实这道题如果你会递推,搞清楚问题的本质就很简单了 首先我们要知道加法原理,加法原理是什么呢?举个栗子:如果我们去上海只可以坐火车,坐飞机。而火车有n班次,飞机有m班次。那么总共去上海就有(n+...
  • qq_28753451
  • qq_28753451
  • 2018年01月28日 21:18
  • 16
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:洛谷 P1002 过河卒
举报原因:
原因补充:

(最多只允许输入30个字)