【动态规划】象棋里马走到指定位置的方法数(java)

265 篇文章 2 订阅
235 篇文章 0 订阅

马走到指定位置的方法数

  • 想象一个象棋的棋盘,
  • 然后把整个棋盘放入第一象限,棋盘的最左下角是(0,0)位置
  • 那么整个棋盘就是横坐标上9条线、
  • 纵坐标上10条线的区域 给你三个
  • 参数 x,y,k
  • 返回“马”从(0,0)位置出发,必须走k步
  • 最后落在(x,y)上的方法数有多少种?

暴力递归

解题思路:
马是走日的,那么在一个位置,他就有八个方向能走,
我们只需要递归这八个方向。然后把方法数累加就行了。
每走一步,剩余步数减一。
递归规程知道了,
下面要确认下,base case
.剩余0步时,如果此时在指定位置,就返回1,不在指定位置,代表走法不正确,返回0.
还有就是临界值检测,不能跳出棋盘,跳出棋盘,认为其走法不对,返回0;
好了,可以撸代码了:

代码演示

/**
     * 10 * 9 的棋盘  x 轴 是10 ,y 轴 是9 
     * @param a x轴上坐标
     * @param b y 轴上坐标
     * @param k 要走几步
     * @return
     */
    public static int jump(int a,int b,int k){
        return process(0,0,k,a,b);
    }

    /**
     * 递归
     * @param x x位置
     * @param y y位置
     * @param k 步数 
     * @param a 要到达指定点的x轴位置
     * @param b 指定点的 y 轴位置
     * @return
     */
    public static int process(int x,int y,int k,int a,int b){
        //棋盘边缘检测,跳出棋盘,认为其当前走法是不合法的,返回0.
        if (x > 9 || x < 0 || y > 8 || y < 0){
            return 0;
        }
        //步数走完时,在指定位置,返回1,不在指定位置返回0.
        if(k == 0){
            return (x == a && y == b) ? 1 : 0;
        }
        //下面八个方向开始递归
        int ways = process(x-2,y+1,k-1,a,b);
        ways += process(x-1,y+2,k-1,a,b);
        ways += process(x+1,y+2,k-1,a,b);
        ways += process(x+2,y+1,k-1,a,b);

        ways += process(x+2,y-1,k-1,a,b);
        ways += process(x+1,y-2,k-1,a,b);
        ways += process(x-1,y-2,k-1,a,b);
        ways += process(x-2,y-1,k-1,a,b);
        //八个方向的累加和 就是方法数
        return ways;
    }

动态规划

动态规划就是对递归的改写,
三个步骤,
一.根据base case 初始化动态规划表,
二.把递归过程改成从表中拿数据的过程
三.返回值就是递归的最初始调用状态
。这个里的动态规划表三个三维数组。不过步骤是一样的,代码演示。

代码演示

   /**
     * 动态规划
     * @param a 指定位置的 x 轴位置
     * @param b 指定位置的y 轴位置
     * @param k 需要走K 步
     * @return
     */
    public static int dp(int a,int b,int k){
        //动态规划表, 10 x 轴  9 y轴,K + 1 是K 步。
        int[][][] dp = new int[10][9][k+1];
        //base case 里 K == 0 时,a,b 位置是1,其他位置是0
        dp[a][b][0] = 1;
        //把递归改成从表格中拿,逻辑是一样的
        for (int step = 1;step <= k;step++){
            for (int x = 0;x <= 9;x++){
                for (int y = 0;y <= 8;y++){
                    int ways = check(x-2,y+1,step-1,dp) ;
                    ways +=  check(x-1,y+2,step-1,dp);
                    ways +=  check(x+1,y+2,step-1,dp);
                    ways +=  check(x+2,y+1,step-1,dp);
                    ways +=  check(x+2,y-1,step-1,dp);
                    ways +=  check(x+1,y-2,step-1,dp);
                    ways +=  check(x-1,y-2,step-1,dp);
                    ways +=   check(x-2,y-1,step-1,dp);
                    dp[x][y][step] = ways;
                }
            }
        }
        //返回递归的初始状态
        return dp[0][0][k];
    }

    /**
     * 检查有没有越界,越界直接返回0
     * @param x
     * @param y
     * @param k
     * @param dp
     * @return
     */
    public static int check(int x,int y,int k, int[][][] dp){
        if (x > 9 || x < 0 || y > 8 || y < 0){
            return 0;
        }
        return dp[x][y][k];
    }

动态规划专题

最长回文子序列

leetcode1143. 最长公共子序列

leetcode.486. 预测赢家

数字转字符串,有多少种转化结果

背包问题–填满背包的最大价格

leetcode–N 皇后 II

凑零钱问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值