0
点赞
收藏
分享

微信扫一扫

1219.黄金矿工

素的盐 2022-02-05 阅读 106

题目

1219.黄金矿工

题目大意

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0

为了使收益最大化,矿工需要按以下规则来开采黄金:

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

样例

image-20220205143629387

数据规模

image-20220205143638271

思路

n n n为网格的行数, m m m为网格的列数,并且由数据可以发现 1 < = n , m < = 15 1<=n,m<=15 1<=n,m<=15。那么可以直接考虑回溯算法。只要 g r i d [ i ] [ j ] > 0 grid[i][j]>0 grid[i][j]>0就说明它可以作为起点,然后开始 d f s + 回 溯 dfs+回溯 dfs+。枚举所有的路径,并且每次更新 a n s = m a x ( a n s , w ) ans=max(ans,w) ans=max(ans,w)。每次 d f s dfs dfs的步骤:

  • d f s dfs dfs传入的参数 w w w来更新答案 a n s ans ans,最大化 a n s ans ans
  • 枚举下一个位置 ( n e x , n e y ) (nex,ney) (nex,ney),可以走上下左右四个方向。保证下一个位置之前没有到达过( v i s vis vis没有被标记过)并且 g r i d [ n e x ] [ n e y ] > 0 grid[nex][ney]>0 grid[nex][ney]>0
  • d f s dfs dfs之后进行回溯, v i s vis vis标记取消。

代码

class Solution {
public:
    int ans=0,n,m;
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    int vis[20][20];
    void dfs(int x,int y,int w,vector<vector<int>>& grid){
        ans=max(ans,w); 
        for(int i=0;i<4;i++){
            int nex=x+dx[i],ney=y+dy[i];
            if(nex>=0&&nex<=n-1&&ney>=0&&ney<=m-1&&grid[nex][ney]&&!vis[nex][ney]){
                vis[nex][ney]=1;
                dfs(nex,ney,w+grid[nex][ney],grid);
                vis[nex][ney]=0;
            }
        }
    }
    int getMaximumGold(vector<vector<int>>& grid) {
        n=grid.size(),m=grid[0].size();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(grid[i][j])
                vis[i][j]=1;
                dfs(i,j,grid[i][j],grid);
                vis[i][j]=0;
            }
        }
        return ans;
    }
};
举报

相关推荐

0 条评论