P1002 [NOIP2002 普及组] 过河卒

题目描述
棋盘上 � A 点有一个过河卒,需要走到目标 � B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 � C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,� A 点 (0,0)(0,0)、� B 点 (�,�)( n, m),同样马的位置坐标是需要给出的。

现在要求你计算出卒从 � A 点能够到达 � B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 � B 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
输入输出样例
输入 #1复制
6 6 3 3
输出 #1复制
6
说明/提示
对于 100%100% 的数据,1≤�,�≤201≤ n, m≤20,0≤0≤ 马的坐标 ≤20≤20。
【题目来源】
NOIP 2002 普及组第四题
  1. 该题是一个动态规划的题目,在做该类题目时有以下几个步骤:

  • 确定状态

简单的说,就是解动态规划时需要开一个数组,数组的每个元素f[i]或者f[i][j]代表什么,类似解数学题中,xyz代表什么一样,具体分为下面两个步骤:

-------研究最优策略的最后一步

-------化为子问题

  • 转移方程

根据子问题定义直接得到

  • 初始条件和边界情况

初始条件一般都是a[0]、a[1]这种,多看看

边界条件主要是看数组的边界,数组越不越界

  • 计算顺序

利用之前的计算结果

  1. 卒每次只可以走右或下,那么可知当前的格子就是由(i,j-1)和(i-1,j)得到。

  1. 状态转移方程为:d(i,j)=d(i-1,j)+d(i,j-1)。

  1. 因为该题目还有一个马要考虑,所以在赋初值时要考虑下标不能越界,所以我们要加两层“保护层“然后将马的范围都赋值记录下来。

#include"stdio.h"
long long e[30][30];
int b[30][30];//标记马拦住的点 
int  fx[8]={-2,-1,1,2,2,1,-1,-2},fy[8]={1,2,2,1,-1,-2,-2,-1};
int bx,by,cx,cy;
main()
{
    int i,j;
    scanf("%d %d %d %d",&bx,&by,&cx,&cy);
    bx+=2;by+=2;cx+=2;cy+=2;//防止越界 
    e[2][1]=1;//初始化
    b[cx][cy]=1;//标记马的位置
    for(i=0;i<8;i++) b[cx+fx[i]][cy+fy[i]]=1;
    for(i=2;i<=bx;i++)
    for(j=2;j<=by;j++)
    {
        if(b[i][j]) continue;//马拦住了跳过 
        e[i][j]=e[i-1][j]+e[i][j-1];//状态转移方程 
     } 
     printf("%lld",e[bx][by]);
}

你可能感兴趣的:(算法)