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

目录
  • 题目描述
  • 示例
  • 解题思路

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

题目描述

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 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++黄金矿工内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言 风靡一时的黄金矿工游戏实现流程详解

    游戏的玩法主要是通过不断采集地下的黄金和钻石,来得到更高的积分.只有完成任务目标,才可以通过相应的关卡.游戏画面中沙滩上的人物便是玩家的角色,下方深褐色的部分是地下,而黄金和钻石就是玩家需要采集的物品.人物右边的四个方框里的物品是游戏中可以使用的道具. 画面中的虚线就是游戏中的探测器,探测器会不断的左右摆动,当摆动到地下的黄金和钻石的位置时,只需要点击矿坑任意处,便可以发射勘探头采集到这些物品,当然一定要瞄准好再出手呦. 当然想要顺利采集到丰富的资源也不是那么简单的,地下矿坑中,会有各式各样的困

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

    目录 题目描述 示例 解题思路 顺心的人大抵一样,坎坷的人各有各的坎坷.也只能坚持自我修行,等待自己的机遇. 题目描述 你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注.每个单元格中的整数就表示这一单元格中的黄金数量:如果该单元格是空的,那么就是 0. 为了使收益最大化,矿工需要按以下规则来开采黄金: 每当矿工进入一个单元,就会收集该单元格中的所有黄金. 矿工每次可以从当前位置向上下左右四个方向走. 每个单元格只能被开采(进入)一

  • PHP回溯法解决0-1背包问题实例分析

    本文实例讲述了PHP回溯法解决0-1背包问题的方法.分享给大家供大家参考.具体分析如下: 这段代码是根据<软件设计师>教程的伪代码写的: 最麻烦的不是伪代码改成php,而是数组下标从0开始,及相应的下标判断问题: 带着调试输出一块写上 <?php $v_arr = array(11,21,31,33,43,53,55,65); $w_arr = array(1,11,21,23,33,43,45,55); $n = count($w_arr ); //测试输出 var_dump(bkna

  • C++基于回溯法解决八皇后问题示例

    本文实例讲述了C++基于回溯法解决八皇后问题的方法.分享给大家供大家参考,具体如下: 回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法.这种方法适用于解一些组合数相当大的问题. 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树.算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解.如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯:否则,进入该子树,继续按深度优先策略搜索. 回溯法指导思想--走不通,就掉头.设计过程:确

  • C#使用回溯法解决背包问题实例分析

    本文实例讲述了C#使用回溯法解决背包问题的方法.分享给大家供大家参考.具体如下: 背包问题描述: 给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高 实现代码: using System; using System.Collections.Generic; using System.Text; namespace BackRack { //要装入书包的货物节点 class BagNode { public int mark;//货物编号,从0开始

  • Python基于回溯法解决01背包问题实例

    本文实例讲述了Python基于回溯法解决01背包问题.分享给大家供大家参考,具体如下: 同样的01背包问题,前面采用动态规划的方法,现在用回溯法解决.回溯法采用深度优先策略搜索问题的解,不多说,代码如下: bestV=0 curW=0 curV=0 bestx=None def backtrack(i): global bestV,curW,curV,x,bestx if i>=n: if bestV<curV: bestV=curV bestx=x[:] else: if curW+w[i]

  • c++回溯法解决1到9之间插入加减或空使运算结果为100

    目录 问题分析 代码展示 问题分析 这时我最近偶然看到的一道题目,发现实现起来还确实有些麻烦,所以把实现的过程记录下来. 这种要罗列出所有结果的问题,我一般是采用回溯法解决的,说的通俗一点就是暴力解法,去遍历所有的情况. 这个问题有一点比较难处理的地方就在于有这个"什么都不插入"这个选项,所以干脆单独拎出来解决.也就是先把1-9这9个数组相互组合,形成一个数组,比如: {1,2,3,4,5,6,7,8,9} {1,2,3,4,5,6,7,89} {1,2,3,4,5,6,78,9} {

  • Java回溯法解决全排列问题流程详解

    题目描述: 给定一不重复的数组,返回其具有的所有全排列(使用 List<List > 返回) 思路: 以数组 nums = [1, 2, 3] 为例,其具有的解空间可以用这样一棵树表示,相比看到这里大家就可以知道,这是一道可以用 回溯法 解决的题. 难点:如何保证不选到已经使用过的数组元素 —— 使用 used[] 数组标记该元素是否被使用过 细节请看代码注释 // 用于存储结果的数组 List<List<Integer>> ans = new ArrayList<

  • Python使用回溯法子集树模板解决迷宫问题示例

    本文实例讲述了Python使用回溯法解决迷宫问题.分享给大家供大家参考,具体如下: 问题 给定一个迷宫,入口已知.问是否有路径从入口到出口,若有则输出一条这样的路径.注意移动可以从上.下.左.右.上左.上右.下左.下右八个方向进行.迷宫输入0表示可走,输入1表示墙.为方便起见,用1将迷宫围起来避免边界问题. 分析 考虑到左.右是相对的,因此修改为:北.东北.东.东南.南.西南.西.西北八个方向.在任意一格内,有8个方向可以选择,亦即8种状态可选.因此从入口格子开始,每进入一格都要遍历这8种状态.

  • PHP基于回溯算法解决n皇后问题的方法示例

    本文实例讲述了PHP基于回溯算法解决n皇后问题的方法.分享给大家供大家参考,具体如下: 这里对于n皇后问题就不做太多的介绍,相关的介绍与算法分析可参考前面一篇C++基于回溯法解决八皇后问题. 回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法.这种方法适用于解一些组合数相当大的问题. 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树.算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解.如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向

  • Python基于回溯法子集树模板解决0-1背包问题实例

    本文实例讲述了Python基于回溯法子集树模板解决0-1背包问题.分享给大家供大家参考,具体如下: 问题 给定N个物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大? 分析 显然,放入背包的物品,是N个物品的所有子集的其中之一.N个物品中每一个物品,都有选择.不选择两种状态.因此,只需要对每一个物品的这两种状态进行遍历. 解是一个长度固定的N元0,1数组. 套用回溯法子集树模板,做起来不要太爽!!! 代码 '''0-

随机推荐