题目
leetcode
你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。
为了使收益最大化,矿工需要按以下规则来开采黄金:
- 每当矿工进入一个单元,就会收集该单元格中的所有黄金。
- 矿工每次可以从当前位置向上下左右四个方向走。
- 每个单元格只能被开采(进入)一次。
- 不得开采(进入)黄金数目为 0 的单元格。
- 矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。
思路
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在提交的时候会把全局变量通用,所以就尽量少定义全局变量,或者是定义不会改变的全局变量。