鱼C论坛

 找回密码
 立即注册
查看: 1694|回复: 1

[技术交流] C++刷LeetCode(1463. 摘樱桃 II)【动态规划***】

[复制链接]
发表于 2021-1-8 13:49:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目描述:
给你一个 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 = [[3,1,1],[2,5,1],[1,5,5],[2,1,1]]
输出:24
解释:机器人 1 和机器人 2 的路径在上图中分别用绿色和蓝色表示。
机器人 1 摘的樱桃数目为 (3 + 2 + 5 + 2) = 12 。
机器人 2 摘的樱桃数目为 (1 + 5 + 5 + 1) = 12 。
樱桃总数为: 12 + 12 = 24 。
示例 2:



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

输入:grid = [[1,0,0,3],[0,0,0,3],[0,0,3,3],[9,0,3,3]]
输出:22
示例 4:

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

提示:

rows == grid.length
cols == grid[i].length
2 <= rows, cols <= 70
0 <= grid[i][j] <= 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[0].size();
        vector<vector<vector<int> > > dp(len1, vector<vector<int> >(len2,vector<int>(len2, INT_MIN)));
        dp[0][0][len2-1] = grid[0][0] + grid[0][len2-1];
        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[i][j][k] = max(dp[i][j][k],dp[i-1][p][q] + grid[i][j] + grid[i][k]);
                        }
                    }
                    res = max(res, dp[i][j][k]);
                }
            }
        }
        return res;
    }
};

代码参考链接:https://leetcode-cn.com/problems ... 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[row][col1];
        return grid[row][col1] + grid[row][col2];
    }
    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[0].size();
        return dfs(0, 0, len2 - 1, grid);
    }
};


参考链接:https://leetcode-cn.com/problems ... code-solution-v2k5/

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-8 13:51:49 | 显示全部楼层
这道题对我来说有点难度,现在还没完全想明白为什么1.自底向上的动态规划中j和k不能相等?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 06:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表