27.黄金矿工(medium)

1.题目链接:

1219. 黄金矿工 - 力扣(LeetCode)1219. 黄金矿工 - 你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。为了使收益最大化,矿工需要按以下规则来开采黄金: * 每当矿工进入一个单元,就会收集该单元格中的所有黄金。 * 矿工每次可以从当前位置向上下左右四个方向走。 * 每个单元格只能被开采(进入)一次。 * 不得开采(进入)黄金数目为 0 的单元格。 * 矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。 示例 1:输入:grid = [[0,6,0],[5,8,7],[0,9,0]]输出:24解释:[[0,6,0], [5,8,7], [0,9,0]]一种收集最多黄金的路线是:9 -> 8 -> 7。示例 2:输入:grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]输出:28解释:[[1,0,7], [2,0,6], [3,4,5], [0,3,0], [9,0,20]]一种收集最多黄金的路线是:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7。 提示: * 1 <= grid.length, grid[i].length <= 15 * 0 <= grid[i][j] <= 100 * 最多 25 个单元格中有黄金。https://leetcode.cn/problems/path-with-maximum-gold/description/2.题目描述:

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格     grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。​
    为了使收益最大化,矿工需要按以下规则来开采黄金:





每当矿工进入一个单元,就会收集该单元格中的所有黄金。矿工每次可以从当前位置向上下左右四个方向走。

每个单元格只能被开采(进入)一次。

不得开采(进入)黄金数目为 0 的单元格。​
矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。​

 示例 1:​
输入:grid = [[0,6,0],[5,8,7],[0,9,0]]​
输出:24​
解释:
[[0,6,0],​
 [5,8,7],​
 [0,9,0]]​
一种收集最多黄金的路线是:9 -> 8 -> 7。​

     示例 2:​
             输入:grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]​
             输出:28​
     解释:
             [[1,0,7],​
              [2,0,6],​
              [3,4,5],​
              [0,3,0],​
              [9,0,20]]​
             一种收集最多黄金的路线是:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7。​
     提示:
             1 <= grid.length, grid[i].length <= 15​
             0 <= grid[i][j] <= 100​
             最多 25 个单元格中有黄金。​
3. 解法:
算法思路:
枚举矩阵中所有的位置当成起点,来一次深度优先遍历,统计出所有情况下能收集到的黄金数的最大值即可。

Java算法代码:

class Solution {
    boolean[][] vis;
    int m,n;
    int[] dx = {0,0,-1,1};
    int[] dy = {1,-1,0,0};
    int ret;
    public int getMaximumGold(int[][] g) {
        m = g.length; n =g[0].length;
        vis = new boolean[m][n];
        for(int i =0;i<m;i++)
            for(int j =0;j<n;j++)
                if(g[i][j] != 0){
                    vis[i][j] = true;
                    dfs(g,i,j,g[i][j]);
                    vis[i][j] = false;
                }
        return ret;
    }
    public void dfs(int[][] g, int i,int j, int path){
        ret = Math.max(ret,path);
        for(int k = 0; k < 4; k++){
            int x = i + dx[k], y = j + dy[k];
            if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && g[x][y] !=0){
                vis[x][y] = true;
                dfs(g,x,y,path+g[x][y]);
                vis[x][y] = false;
            }
        }
    }
}

运行结果:

递归展开:

有了前面题目的铺垫,这个几乎是一模一样,只是一些细节不一样。

刚才是不同的开始字母,现在是不为0的。

这里是需要取最大值,不需要记录

递归中其他的都一模一样

---------------------------------------------------------------------------------------------------------------------------------

记住,相信你的递归函数,它可以做到!

记住,不理解时候,去尝试手动展开!

记住,逻辑展开(你不可能对所有的题目都进行手动展开)!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值