目录

力扣1463.-摘樱桃-II

力扣1463. 摘樱桃 II

力扣1463. 摘樱桃 II

题目

https://i-blog.csdnimg.cn/direct/667961fcdf6f445a8a443993939ca4b5.png#pic_center

题目解析及思路

题目要求返回从左上角和右上角分别出发两个机器人摘樱桃的最大数量、

每个机器人可以往左下,正下,右下三个方向走

定义 f[i][j+1][k+1] 表示一个机器人从 (i,j) 出发,一个机器人从 (i,k) 出发的最多摘樱桃数量

边界: j=−1, k=−1

初始值: f[i][j][k] = 0 答案为 f[0][1][m]

代码

class Solution {
public:
    int cherryPickup(vector<vector<int>>& grid) {
        int n = grid.size(),m = grid[0].size();
        vector<vector<vector<int>>> f(n + 1, vector<vector<int>>(m + 2, vector<int>(m + 2)));
        for(int i=n-1;i>=0;i--){
            //哪怕左上角的机器人一直往右下走,j也不会超过i,最多就相等,所以j>i的情况都不存在
            for(int j=0;j<min(m,i+1);j++){
                //哪怕右上角的机器人一直往左下走,k也不会超过m-i-1,最多就相等,所以这种情况都不存在
                //并且两机器人线路交叉也没意义,如果穿过去能更多,那更近的机器人应该自己走那条路,所以k>j
                for(int k=max(j+1,m-1-i);k<m;k++){
                    //九种情况取max:[j...j+2] × [k...k+2]
                    f[i][j+1][k+1] = max({
                        f[i + 1][j][k], f[i + 1][j][k + 1], f[i + 1][j][k + 2],
                        f[i + 1][j + 1][k], f[i + 1][j + 1][k + 1], f[i + 1][j + 1][k + 2],
                        f[i + 1][j + 2][k], f[i + 1][j + 2][k + 1], f[i + 1][j + 2][k + 2]
                    }) + grid[i][j] + grid[i][k];
                }
            }
        }
        return f[0][1][m];
    }
};