难度中等182收藏分享切换为英文接收动态反馈
你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 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 个单元格中有黄金。
思路:实际上阅读本题就可以发现本题就是一个DFS问题,当然实际更严格的应该说是回溯法,因为每个位置可能存在多个可决策方向,因此需要取拥有最大金矿和的路径,在实际的实现中,我们有更简单的做法,就是每一层DFS都取max,因为矿的价值一定大于0,因此同一条路径上,到大终点时的矿和一定比路径上其他点大。
class Solution {
public:
int n, m, max_golden = 0, dir[4][2] = {
{0, -1},
{0, 1},
{1, 0},
{-1, 0},
};
void DFS(vector<vector<int>>& grid, int sx, int sy, int sum_value){//DFS实现
max_golden = max(sum_value, max_golden);
int x, y, nx, ny, index, temp_value;
for(index = 0; index < 4; ++ index){
nx = sx + dir[index][0];
ny = sy + dir[index][1];
if(nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny]){
temp_value = grid[nx][ny];
grid[nx][ny] = 0;
DFS(grid, nx, ny, sum_value + temp_value);
grid[nx][ny] = temp_value;
}
}
}
int getMaximumGold(vector<vector<int>>& grid) {
int i, j, temp_value;
n = grid.size(), m = grid[0].size();
for(i = 0; i < n; ++ i){
for(j = 0; j < m; ++ j){
if(grid[i][j]) {
temp_value = grid[i][j];
grid[i][j] = 0;
DFS(grid, i, j, temp_value);
grid[i][j] = temp_value;
}
}
}
return max_golden;
}
};