糖逗 发表于 2021-1-8 13:49:59

C++刷LeetCode(1463. 摘樱桃 II)【动态规划***】

题目描述:
给你一个 rows x cols 的矩阵 grid 来表示一块樱桃地。 grid 中每个格子的数字表示你能获得的樱桃数目。

你有两个机器人帮你收集樱桃,机器人 1 从左上角格子 (0,0) 出发,机器人 2 从右上角格子 (0, cols-1) 出发。

请你按照如下规则,返回两个机器人能收集的最多樱桃数目:

从格子 (i,j) 出发,机器人可以移动到格子 (i+1, j-1),(i+1, j) 或者 (i+1, j+1) 。
当一个机器人经过某个格子时,它会把该格子内所有的樱桃都摘走,然后这个位置会变成空格子,即没有樱桃的格子。
当两个机器人同时到达同一个格子时,它们中只有一个可以摘到樱桃。
两个机器人在任意时刻都不能移动到 grid 外面。
两个机器人最后都要到达 grid 最底下一行。
 

示例 1:



输入:grid = [,,,]
输出:24
解释:机器人 1 和机器人 2 的路径在上图中分别用绿色和蓝色表示。
机器人 1 摘的樱桃数目为 (3 + 2 + 5 + 2) = 12 。
机器人 2 摘的樱桃数目为 (1 + 5 + 5 + 1) = 12 。
樱桃总数为: 12 + 12 = 24 。
示例 2:



输入:grid = [,,,,]
输出:28
解释:机器人 1 和机器人 2 的路径在上图中分别用绿色和蓝色表示。
机器人 1 摘的樱桃数目为 (1 + 9 + 5 + 2) = 17 。
机器人 2 摘的樱桃数目为 (1 + 3 + 4 + 3) = 11 。
樱桃总数为: 17 + 11 = 28 。
示例 3:

输入:grid = [,,,]
输出:22
示例 4:

输入:grid = [,]
输出:4
 

提示:

rows == grid.length
cols == grid.length
2 <= rows, cols <= 70
0 <= grid <= 100 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cherry-pickup-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。



1.自底向上的动态规划
class Solution {
public:
    int cherryPickup(vector<vector<int>>& grid) {
      int len1 = grid.size(), len2 = grid.size();
      vector<vector<vector<int> > > dp(len1, vector<vector<int> >(len2,vector<int>(len2, INT_MIN)));
      dp = grid + grid;
      int res = INT_MIN;
      for(int i = 1; i < len1; i++){
            for(int j = 0; j < len2-1; j++){
                for(int k = j+1; k < len2; k++){
                  for(int p = max(j-1, 0); p <= min(j+1, len2-2); p++){
                        for(int q = max(k-1, 1);q <= min(k+1, len2-1); q++){
                            if(p >= q)continue;
                            dp = max(dp,dp + grid + grid);
                        }
                  }
                  res = max(res, dp);
                }
            }
      }
      return res;
    }
};

代码参考链接:https://leetcode-cn.com/problems/cherry-pickup-ii/solution/dong-tai-gui-hua-by-hust_dhc-26/



2.自顶向下的动态规划(超时)
class Solution {
private:
    int len1, len2;
    //下一层col1和col2的取值
    vector<int>direct = {-1, 0, 1};
public:
    int get_value(int row, int col1, int col2, vector<vector<int>> grid){
      if(col1 == col2)return grid;
      return grid + grid;
    }
    int dfs(int row, int col1, int col2, vector<vector<int>> grid){
      if(row == len1 - 1)return get_value(row, col1, col2, grid);
      //下一层的最优解
      int temp = 0;
      for(auto temp1 : direct){
            for(auto temp2 : direct){
                int store1 = temp1 + col1, store2 = temp2 + col2;
                //确保没有越界
                if(store1 >= 0 && store1 < len2 && store2 >= 0 && store2 < len2){
                  temp = max(temp, dfs(row+1, store1, store2, grid));
                }
            }
      }
      return temp + get_value(row, col1, col2, grid);
    }
    int cherryPickup(vector<vector<int>>& grid) {
      //自顶向下的动态规划
      len1 = grid.size(), len2 = grid.size();
      return dfs(0, 0, len2 - 1, grid);
    }
};


参考链接:https://leetcode-cn.com/problems/cherry-pickup-ii/solution/zhai-ying-tao-ii-by-leetcode-solution-v2k5/

糖逗 发表于 2021-1-8 13:51:49

这道题对我来说有点难度,现在还没完全想明白为什么1.自底向上的动态规划中j和k不能相等?{:10_266:}
页: [1]
查看完整版本: C++刷LeetCode(1463. 摘樱桃 II)【动态规划***】