• 洛谷:过河卒


    题目描述

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

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

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

    输入输出格式

    输入格式:

     

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

     

    输出格式:

     

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

     

    输入输出样例

    输入样例#1: 复制
    6 6 3 3
    
    输出样例#1: 复制
    6
    

    说明

    结果可能很大!

    思路过程

    第一感觉,就想用深度优先搜索做,然后里面wa最后还超时一发。。。后面自己仔细想了一下,如果深度优先和广度优先,那么肯定是不对的,因为无论是深搜还广度优先搜索,最坏结果都是需要遍历每个点,这样遍历每个点复杂度是2^n,稳稳的超时。。。后来想想,其实不妨这样想,每个点只可能从上面和左边推过来,这样就从第一个点往后推即可,转移方程:

    dp[i][j]=dp[i-1][j]+dp[i][j-1]

    这应该是递推,不能算是动态规划,最后提醒一点,在判断马控制的位置需要判断一下边界条件不然。。。会被坑(下次一定要记住)

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int mv[2][10]={{0,-2,-2,-1,-1,1,1,2,2},{0,1,-1,2,-2,2,-2,1,-1}};//用二维数值写方向很方便
    long long dp[25][25];
    bool visit[25][25];
    int main(){
      int nx,ny,hx,hy;
      scanf("%d%d%d%d",&nx,&ny,&hx,&hy);
      memset(dp,0,sizeof(dp));
      memset(visit,0,sizeof(visit));
      for(int i=1;i<=8;i++){
        if (hx+mv[0][i]>=0 && hx+mv[0][i]<=nx && hy+mv[1][i]>=0 && hy+mv[1][i]<=ny)
        visit[hx+mv[0][i]][hy+mv[1][i]]=1;
      }
      visit[hx][hy]=1;
      dp[0][0]=1;
      for(int i=0;i<=nx;i++){
        for(int j=0;j<=ny;j++){
          if (i)
             dp[i][j]+=dp[i-1][j];
          if (j)
             dp[i][j]+=dp[i][j-1];
              dp[i][j]*=!visit[i][j];
        }
      }
      printf("%lld",dp[nx][ny]);
      return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    2040 打开所有的灯
    1323 删数问题(加强版)
    1087 FBI树
    1030 求先序排列
    1743 矩阵Ⅲ
    svn更新时,出现不知道这样的主机的解决方案
    用jquery或js获取select标签中选中的option值及文本
    html页面中的button按钮会自动提交form表单的问题以及解决方案
    localStorage与sessionStorage的使用和区别
    命令行mvn打包
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/9338806.html
Copyright © 2020-2023  润新知