C++使用回溯法解决黄金矿工问题

 更新时间:2022年10月08日 09:57:08   作者:刘婉晴  
在矩阵中考察回溯算法,分为任意起点、左上角开始等情况。从而有不同的模板,其实区别就是直接开始还是每个坐标都去尝试,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

顺心的人大抵一样,坎坷的人各有各的坎坷。也只能坚持自我修行,等待自己的机遇。

题目描述

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。

为了使收益最大化,矿工需要按以下规则来开采黄金:

  • 每当矿工进入一个单元,就会收集该单元格中的所有黄金。
  • 矿工每次可以从当前位置向上下左右四个方向走。
  • 每个单元格只能被开采(进入)一次。
  • 不得开采(进入)黄金数目为 0 的单元格。
  • 矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。

链接:https://leetcode.cn/problems/path-with-maximum-gold (力扣)

示例

解题思路

这是一道典型的矩阵 回溯 的题目,依旧是回溯三步走:

1. 回溯函数参数:

  • int[][] grid 表示金矿的矩阵
  • int gold 表示当前路径收集到的金子的总和
  • int x, int y 表示收集到了第 grid[x][y] 位置

下面让我们来思考一个问题:本题需要建立一个 boolean[][] used 备忘录嘛?

备忘录是一定需要的,但是对本题来说,可以通过把已经遍历过的 grid[x][y] 的值改为 0,以此来实现备忘录,这样更能节省空间。

2. 结束条件:

当前遍历位置(x,y)越界,或者当前遍历位置没有金子(grid[x][y] == 0)时,结束return。

3. 单层逻辑:

int temp = grid[x][y]; // 记录值,以便回溯时恢复
gold += grid[x][y]; // 将当前值加入 gold 和中
max = Math.max(max, gold); // 更新结果
grid[x][y] = 0; // 将 grid[x][y] 置为0,防止出现同一重复重复使用

然后递归调用4次 dfs()函数,分布对应从 (x,y)向上下左右前进

回溯部分:

grid[x][y] = temp; // 回溯,恢复 grid[x][y] 

代码:

class Solution {
    int max = Integer.MIN_VALUE;
    public int getMaximumGold(int[][] grid) {
        for(int i=0; i<grid.length; i++){
            for (int j=0; j<grid[0].length; j++){
                if(grid[i][j] != 0) { // 从每个非0位置都可以开始
                    dfs(grid, 0, i, j);
                }
            }
        }
        return max==Integer.MIN_VALUE?0:max;
    }
    public void dfs(int[][] grid, int gold, int x, int y){
        if(!isOk(grid, x, y)){ // 判断是否越界或到无金子位置,结束
            return;
        }
        int temp = grid[x][y];
        gold += grid[x][y];
        max = Math.max(max, gold); // 更新最大值
        grid[x][y] = 0; // 防止出现重复遍历
        dfs(grid, gold, x+1, y); //向上
        dfs(grid, gold, x-1, y); //向下
        dfs(grid, gold, x, y+1); //向左
        dfs(grid, gold, x, y-1); // 向右
        grid[x][y] = temp; // 回溯
    }
	// 判断是否越界 或 走到了无金子位置
    public boolean isOk(int[][] grid, int x, int y){
        if(x<0 || x>=grid.length || y<0 || y>=grid[0].length || grid[x][y] == 0){
            return false;
        }
        return true;
    }
}

本题类似的题还有岛屿问题,可以移步到 岛屿问题

到此这篇关于C++使用矩阵回溯法解决黄金矿工问题的文章就介绍到这了,更多相关C++黄金矿工内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ 实现旋转蛇错觉的详细代码

    C++ 实现旋转蛇错觉的详细代码

    这篇文章主要介绍了C++ 实现旋转蛇错觉的详细代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • OpenCV实现相机标定板

    OpenCV实现相机标定板

    这篇文章主要为大家详细介绍了OpenCV实现相机标定板,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • 用C语言来实现一个简单的虚拟机

    用C语言来实现一个简单的虚拟机

    这篇文章主要介绍了用C语言来实现一个简单的虚拟机,其中栈数组的部分非常值得学习,需要的朋友可以参考下
    2015-07-07
  • C++ GDI实现图片格式转换

    C++ GDI实现图片格式转换

    GDI+(Graphics Device Interface Plus)是一种用于图形绘制和图像处理的应用程序编程接口(API),在Windows平台上广泛使用,本文就来介绍一下如何使用GDI实现图片格式转换吧
    2023-12-12
  • C语言使用链表实现学生籍贯管理系统

    C语言使用链表实现学生籍贯管理系统

    这篇文章主要为大家详细介绍了C语言使用链表实现学生籍贯管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C++中类型推断(auto和decltype)的使用

    C++中类型推断(auto和decltype)的使用

    在C++11之前,每个数据类型都需要在编译时显示声明,在运行时限制表达式的值,但在C++的新版本之后,引入了 auto 和 decltype等关键字,本文就来介绍一下C++中类型推断(auto和decltype)的使用,感兴趣的可以了解一下
    2023-12-12
  • C++ 整数拆分方法详解

    C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧
    2016-08-08
  • C++实现猴子吃桃的示例代码

    C++实现猴子吃桃的示例代码

    这篇文章主要介绍了C++实现猴子吃桃的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • C语言中的结构体内嵌函数用法

    C语言中的结构体内嵌函数用法

    这篇文章主要介绍了C语言中的结构体内嵌函数用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C/C++ 获取自身IP与域名片段的示例代码

    C/C++ 获取自身IP与域名片段的示例代码

    这篇文章主要介绍了C/C++ 获取自身IP与域名片段的示例代码,帮助大家更好的理解和学习C/C++编程,感兴趣的朋友可以了解下
    2020-10-10

最新评论