leetcode1219 黄金矿工 c语言 回溯算法

题目

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

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

思路

grid[x][y]表示的是在xy位置的黄金数量,而这个题目就是找出数量最大的一条路径,所以我们可以用回溯算法
首先将每个点都走一遍,看看每个点能够获取的最多的黄金数,不断的和原有的最大黄金比较,返回答案。这个过程可以用一个dfs函数实现。
首先是更新这条路径的黄金数,gold+=grid,然后因为不能走重复的路,暂时将这个点的黄金数设置为零,当回溯到这个点的时候可以将这个点的黄金数重置回来。
然后就是递归,将下一个四个方向都是一遍。最后就能够得到答案。

代码

void dfs(int** grid, int x, int y, int gold, int colSize, int rowSize, int* ans){ 
    gold += grid[x][y];
    if(gold > *ans){
        *ans = gold;
    }
    int temp = grid[x][y];
    grid[x][y] = 0;
    if(x + 1 < rowSize && grid[x + 1][y] > 0){
        dfs(grid, x + 1, y, gold, colSize, rowSize, ans);
    }
    if(x - 1 >= 0 && grid[x - 1][y] > 0){
        dfs(grid, x - 1, y, gold, colSize, rowSize, ans);
    }
    if(y + 1 < colSize && grid[x][y + 1] > 0){
        dfs(grid, x, y + 1, gold, colSize, rowSize, ans);
    }
    if(y - 1 >= 0 && grid[x][y - 1] > 0){
        dfs(grid, x, y - 1, gold, colSize, rowSize, ans);
    }
    grid[x][y] = temp;
}

int getMaximumGold(int** grid, int gridSize, int* gridColSize){
    int ans = 0, colSize, rowSize;
    rowSize = gridSize;
    colSize = gridColSize[0];
    for(int i = 0; i < rowSize; i++){
        for(int k = 0; k < colSize; k++){
            if(grid[i][k] != 0){
                dfs(grid, i, k, 0, colSize, rowSize, &ans);
            }
        }
    }
    return ans;
}

思考

这里我之前提交的时候有个测试点在本地编译能够通过,在leetcode本身的测试里面这个也是正确答案,但是提交的时候却出错了,后来我发现leetcode在提交的时候会把全局变量通用,所以就尽量少定义全局变量,或者是定义不会改变的全局变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值