算法-跳跃

  1. 看完题之后:这啥啊,这么复杂,每一步都有九种可能,还要考虑他的权重

解题思路:本题的重点是如何计算他的路线,所以我想怎么判断,还要结合他的规则(不能后退),反正想了很长时间,感觉很复杂。想一步一步来,判断他是向下走还是向右走合适,如果向右走一格那么就跟原来下面的三格比较,但是逻辑有问题,就推翻了。后来想到了递归这种解法,每一次判断他九种走法的最合适的值,就是实现起来很难,思路还是卡住了。

  1. 最后想不出来看了别人的答案,那就看看别人的思路吧

这里他先定义了一系列静态变量

    static Scanner sr = new Scanner(System.in);
    static int n = sr.nextInt();
    static int m = sr.nextInt();
    static int[][] map = new int[n][m];
    static int dx[] = {0,0,0,1,2,3,1,2,1};
    static int dy[] = {1,2,3,0,0,0,1,1,2};
    static int max_length = Integer.MIN_VALUE;

其中这两个数组

    static int dx[] = {0,0,0,1,2,3,1,2,1};
    static int dy[] = {1,2,3,0,0,0,1,1,2};
//这种方法非常简便,比我想得简单多了

对应他要走的九种可能

static int max_length = Integer.MIN_VALUE;
//规定了一个最小的int类型的数,方便在以后取较大值
//因为最后的结果可能是负数,所以没有初始位零
//细啊 太细了

输入数据,调用函数,输出,没什么好说的

for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                map[i][j] = sr.nextInt();
            }
        }
        dfs(0,0, map[0][0]);
        System.out.println(max_length);

主要看递归

private static void dfs(int i, int j, int length) {
        // TODO Auto-generated method stub
        if(i==n-1 && j== m-1)
            max_length = Math.max(length, max_length);//更新最长长度
        for (int k = 0; k < dx.length; k++) {
            int nx = i + dx[k];
            int ny = j + dy[k];
            //根据范围内坐标进行递归
            if (nx >= 0 && ny >= 0 && nx < n && ny < m ) {
                dfs(nx,ny,length+map[nx][ny]);//进行递归
            }
        }
    }

先用一个for循环来计算九种走法,每一种走法又调用了一次函数

这里他限制范围用了

nx >= 0 && ny >= 0 && nx < n && ny < m

当上面循环出的结果不在这个范围内就不会进入递归,避免越界,很妙

至于最后为什么没有return,函数出口在哪里,我也是想了很久

整体递归思路 这是3x4的一个图 要走到2.3的点

0.0

2.3

第一次for循环,(0.1)往下走

0.0

0.1

2.3

符合条件,进入递归,再循环,再往下

0.0

0.1

0.2

2.3

这时再for循环,前三次都是向下走,不会进入递归,第四次往右走,符合条件

0.0

0.1

0.2

1.2

2.3

以此类推,直到走到目的地

0.0

0.1

0.2

1.2

2.2

2.3

符合判断条件后最后一次进入递归

因为是第一次完成整个路程,最大的长度就是本次长度

if(i==n-1 && j== m-1)
            max_length = Math.max(length, max_length);//更新最长长度

这时for循环完也不会进入递归,这次的路线就结束了

之后的路线结束后会跟之前的长度比较,取较大的值

这时候就体现了静态变量的用处,也就是在全局有效,不用返回值了

3.提交结果

4.

这次的题对我来说很难,在思考的过程中有了大概的方向,了解了别人的代码也知道了自己跟大佬的差距,要仔细体会别人的做题方式,多学习

5.正确代码

import java.util.Scanner;

public class Main {
    static Scanner sr = new Scanner(System.in);
    static int n = sr.nextInt();
    static int m = sr.nextInt();
    static int[][] map = new int[n][m];
    static int dx[] = {0,0,0,1,2,3,1,2,1};
    static int dy[] = {1,2,3,0,0,0,1,1,2};
    static int max_length = Integer.MIN_VALUE;
public static void main(String[] args) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            map[i][j] = sr.nextInt();
        }
    }
    dfs(0,0, map[0][0]);
    System.out.println(max_length);
}
private static void dfs(int i, int j, int length) {
    // TODO Auto-generated method stub
    if(i==n-1 && j== m-1)
    max_length = Math.max(length, max_length);//更新最长长度
    for (int k = 0; k < dx.length; k++) {
        int nx = i + dx[k];
        int ny = j + dy[k];
        //根据范围内坐标进行递归
        if (nx >= 0 && ny >= 0 && nx < n && ny < m ) {
            dfs(nx,ny,length+map[nx][ny]);//进行递归
        }
    }
}
}

6.错误代码

因为思路没想明白,敲了很多零碎的代码,也没保存

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值