洛谷-P1002-过河卒 (java,100) 【动态规划】

在这里插入图片描述
在这里插入图片描述

可能是太久没做题了,没信心,起初看到这道题,差点就归为不会的类型放弃了。
后面耐心的看,思考了会,好像不难,第一反应就是用递归(一条路走到黑的)思路做,输入测试样例,好像对了 信心满满的提交。

import java.util.Scanner;

public class Main {
    static long count = 0;
    static int bx;
    static int by;
    static int n;
    static int m;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        bx = input.nextInt();
        by = input.nextInt();
        n = input.nextInt();
        m = input.nextInt();
        dp(0, 0);
        System.out.println(count);

    }

    public static void dp(int x, int y) {
    // 找到了一条路,count+1;
        if (x == bx && y == by) {
            count++;
            return;
        }
        //超过边界的情况
        if (x > bx || y > by) {
            return;
        }

		//马挡路的情况。
        if (((x == n + 1 || x == n - 1) && (y == m + 2 || y == m - 2)) || ((x == n + 2 || x == n - 2) && (y == m + 1 || y == m - 1)) || (x == n && y == m)) {
            return;
        }


        dp(x, y + 1);//向下走,
        dp(x + 1, y);//向右走。

    }
}

在这里插入图片描述

看到超时,又想不到哪里可以优化了,就想着,拿出王牌(转用c语言提交),可结果还是一样的,该超时的还是超时了,不死心的下载了他的样例,样例输入为“20 20 4 0”,试了一下自己的程序,好东西,要过这个样例,起码得上个小时,时间能过才怪。

没办法,只能推翻自己原先的思路,冥思(看了一下大神的思路)。
因为题意告诉我们了,只能向下走和向右走。所以反过来,我们要到达那个点,只能依靠那个点的上点和左点到达。
那么我们到达这个点可能的路径条数,就是上一个点和左边一个点的路径条数相加。
即:

1 1 1 1 1 1 1
1 2 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

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        //终点横纵坐标。
        int bx = input.nextInt();
        int by = input.nextInt();
        //马的横纵坐标。
        int n = input.nextInt();
        int m = input.nextInt();
        long[][] chess = new long[bx + 2][by + 2];
        //第一行和第一列舍弃,加上他本身,所以我们范围要加2.
        chess[1][0] = 1;
        // 也可以是chess[0][1] = 1;
        // 但不能是chess[1][1]=1;因为那样会在循环里面被覆盖成0。
        for (int i = 1; i < bx + 2; i++) {
            for (int j = 1; j < by + 2; j++) {
                //判断,如果有马挡路的情况,则跳过。
                //因为我们第一行和第一列舍弃,所以我们马的横纵坐标都得加一。
                if (judge(i, j, n + 1, m + 1)) {
                    continue;
                }
                //如果没有挡路,则到达这个点的路径条数,就是上一个点与左一个点的路径条数相加。
                chess[i][j] = chess[i - 1][j] + chess[i][j - 1];
            }

        }
        //打印最后一个数,即终点数,该数就是能到达终点的路径条数
        System.out.println(chess[bx + 1][by + 1]);

    }

    //判断马挡路的情况
    //1.x=n+1; y=m+2
    //2.x=n+1; y=m-2
    //3.x=n-1; y=m+2
    //4.x=n-1; y=m-2
    //5.x=n+2; y=m+1
    //6.x=n+2; y=m-1
    //7.x=n-2; y=m+1
    //8.x=n-2; y=m-1
    //9.x=n; y=m
    public static boolean judge(int x, int y, int n, int m) {
        if (((x == n + 1 || x == n - 1) && (y == m + 2 || y == m - 2)) || ((x == n + 2 || x == n - 2) && (y == m + 1 || y == m - 1)) || (x == n && y == m)) {
            return true;
        }
        return false;
    }
}

在这里插入图片描述
再一次的领会了算法的强大。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

北海南风

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

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

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

打赏作者

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

抵扣说明:

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

余额充值