题目描述

一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示:

0 表示这个格子是空的,所以你可以穿过它。
1 表示这个格子里装着一个樱桃,你可以摘到樱桃然后穿过它。
-1 表示这个格子里有荆棘,挡着你的路。
你的任务是在遵守下列规则的情况下,尽可能的摘到最多樱桃:

从位置 (0, 0) 出发,最后到达 (N-1, N-1) ,只能向下或向右走,并且只能穿越有效的格子(即只可以穿过值为0或者1的格子);
当到达 (N-1, N-1) 后,你要继续走,直到返回到 (0, 0) ,只能向上或向左走,并且只能穿越有效的格子;
当你经过一个格子且这个格子包含一个樱桃时,你将摘到樱桃并且这个格子会变成空的(值变为0);
如果在 (0, 0) 和 (N-1, N-1) 之间不存在一条可经过的路径,则没有任何一个樱桃能被摘到。
示例 1:
输入: grid =
[[0, 1, -1],
[1, 0, -1],
[1, 1, 1]]
输出: 5
解释:
玩家从(0,0)点出发,经过了向下走,向下走,向右走,向右走,到达了点(2, 2)。
在这趟单程中,总共摘到了4颗樱桃,矩阵变成了[[0,1,-1],[0,0,-1],[0,0,0]]。
接着,这名玩家向左走,向上走,向上走,向左走,返回了起始点,又摘到了1颗樱桃。
在旅程中,总共摘到了5颗樱桃,这是可以摘到的最大值了。
说明:
grid 是一个 N * N 的二维数组,N的取值范围是1 <= N <= 50。
每一个 grid[i][j] 都是集合 {-1, 0, 1}其中的一个数。
可以保证起点 grid[0][0] 和终点 grid[N-1][N-1] 的值都不会是 -1。

分析

本题属于DP里的数字三角形模型,类似的问题有AcWing 1015 摘花生,AcWing 1018 最低通行费,AcWing 1027 方格取数,AcWing 275 传纸条。

题目要求从左上角走到右下角,再从右下角回到左上角,与传纸条问题的不同之处在于,传纸条问题每个人只会帮助一个人传纸条,因此来回不能走相同的方格,但是本题是有樱桃的地方来回都可以走,不过走过一次摘取后第二次路过就没樱桃了。如果我们分两次来走,每次进行状态转移有若干条路径,将其中的樱桃都摘了显然不合适。考虑到从左上角走到右下角和从右下角走到左上角本质是一样的,因此可以看作从左上角走到右下角两次,求两次摘得的樱桃最大数量,为了保证樱桃不被重复摘取,可以设定两个人同时从左上角出发,两人都只能向下或者向右走,这样两个人走到同一个方格时一定是同时到达的,这样就不会重复摘樱桃了。

一般这类问题的状态表示习惯于f[k][x1][x2]表示走了k步,第一个人走到(x1,k-x1),第二个人走到(x2,k - x2)时摘取的樱桃的最大数量,这样第一个维度k的规模是2n,我使用的状态表示是f[i][j][k]表示第一个人走到(i,j),第二个人走到(k,i + j - k)时摘取的最大数量,这样三个维度的规模都是n了。

下面分析状态转移,第一个人到达当前格子可以是向下或者向右走的,第二个人到达当前格子也可以是向下或者向右走的,因此两个人走到当前格子一共有四种走法。如果不设置哨兵,三个维度都需要判断是否大于0,才能够进行状态转移,相当麻烦。所以我们让初始的第一个状态是f[1][1][1],这时的边界状态需要注意,能够到达f[1][1][1]的有四种状态,我们只需要让其中一种状态的初值设置为0就可以了,对于其他状态,状态初始值一律设置为-INF,为什么呢?比如(1,2)格子上的数是-1,表示不可达,我们无法从(1,1)经过(1,2)到达(1,3),但是如果不设置(0,3)的初始值是-INF,默认初始值就是0,那么(1,3)这个格子的状态就变为可达了,我们希望初始状态只有起点是可达的,所以其他状态都设置为-INF。状态边界的设置比状态转移更容易出错。

状态转移方程参考下面的代码,代码表示比较清晰。

代码

class Solution {public:int f[55][55][55];int cherryPickup(vector<vector<int>>& grid) {int n = grid.size();memset(f,-0x3f,sizeof f);f[0][1][0] = 0;for(int i = 1;i <= n;i++) {for(int j = 1;j <= n;j++) {for(int k = 1;k <= n;k++) {int l = i + j - k;if(l < 1 || l > n)   continue;if(grid[i-1][j-1] == -1 || grid[k-1][l-1] == -1) {f[i][j][k] = -0x3f3f3f3f;continue;}int x = max(f[i-1][j][k],f[i-1][j][k-1]);int y = max(f[i][j-1][k],f[i][j-1][k-1]);f[i][j][k] = max(x,y);if(grid[i-1][j-1] == 1) f[i][j][k] += 1;if(grid[k-1][l-1] == 1 && i != k)   f[i][j][k] += 1;//不是相同格子}}}if(f[n][n][n] < 0)    return 0;return f[n][n][n];}
};

leetcode 741. 摘樱桃相关推荐

  1. Leetcode 741. 摘樱桃 C++

    Leetcode 741. 摘樱桃 题目 一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示: 0 表示这个格子是空的,所以你可以穿过它. 1 表示这个格子里装着一 ...

  2. LeetCode 741. 摘樱桃___贪心算法篇__失败

    741. 摘樱桃 一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示: 0 表示这个格子是空的,所以你可以穿过它. 1 表示这个格子里装着一个樱桃,你可以摘到樱桃然 ...

  3. LeetCode 741 摘樱桃(动态规划)

    一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示: 0 表示这个格子是空的,所以你可以穿过它. 1 表示这个格子里装着一个樱桃,你可以摘到樱桃然后穿过它. -1 ...

  4. LeetCode 741. 摘樱桃(dp)

    题意: 一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示:0 表示这个格子是空的,所以你可以穿过它. 1 表示这个格子里装着一个樱桃,你可以摘到樱桃然后穿过它. ...

  5. [leetcode]741摘樱桃,动态规划

    题目表明去终点只能往下和往右,回去只能往上和往左,统计路程中经过的樱桃个数,那么就相当于从起点出发两次到终点,但两次路过到的同个樱桃就不能再重复计算,这两次不分先后,同时走深搜,然后用dp表示每个状态 ...

  6. [LeetCode解题报告] 741. 摘樱桃

    [LeetCode解题报告] 741. 摘樱桃 一. 题目 1. 题目描述 2. 原题链接 二. 解题报告 1. 思路分析 2. 复杂度分析 3. 代码实现 三. 本题小结 一. 题目 1. 题目描述 ...

  7. 【LeetCode】摘樱桃 [H](记忆化搜索)

    741. 摘樱桃 - 力扣(LeetCode) 一.题目 一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示: 0 表示这个格子是空的,所以你可以穿过它. 1 表示 ...

  8. 741.摘樱桃 动态规划

    741.摘樱桃 一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示: 0 表示这个格子是空的,所以你可以穿过它. 1 表示这个格子里装着一个樱桃,你可以摘到樱桃然后 ...

  9. 力扣 741. 摘樱桃

    题目来源:https://leetcode.cn/problems/cherry-pickup/ 大致题意: 给定一个二维数组1,其中数组元素由 0,1,-1 表示,有以下含义: 0 表示该位置可以通 ...

  10. 【741. 摘樱桃】

    来源:力扣(LeetCode) 描述: 一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示: 0 表示这个格子是空的,所以你可以穿过它. 1 表示这个格子里装着一个 ...

最新文章

  1. 使用深度学习方法实现面部表情包识别
  2. spring mvc返回页面显示空白_Spring 框架基础(06):Mvc架构模式简介,执行流程详解...
  3. c语言学生成绩删除功能,c语言学生成绩管理系统程序设计,有添加,查找,删除,输出,修改,排序等功能!!!...
  4. 重写到边缘–充分利用它! 在GlassFish上!
  5. [剑指offer]面试题第[54]题[JAVA][二叉搜索树的第k大节点][递归][迭代]
  6. 大数据就业前景分析的太到位了【附:1T视频资料】
  7. 使用命令编译运行Java程序
  8. matlab2c使用c++实现matlab函数系列教程-load函数
  9. 14.msql_python
  10. 工业机器人市场2018年热点回顾与2019年展望
  11. freeswitch exporter
  12. spss系列——一元线性回归的分析与预测实例
  13. 计算机内存改成多少合适,32g内存需要设置虚拟内存吗?32g内存虚拟内存设置多少合适...
  14. excel 将日期转换为8位数字
  15. 4月书讯 | 一大波好书来袭,最美华章四月天
  16. 骨传导耳机是什么,骨传导耳机对耳朵有什么好处吗
  17. 跨越技术鸿沟:从TCPIP到NDN
  18. PTA 选择结构 7-1 能买手机吗?
  19. JAVA—— 逻辑 结构
  20. 在C语言中,int型数据的取值范围?

热门文章

  1. PLC面向对象编程系列之双通气缸功能块(SMART梯形图)
  2. java读取excel数据的方法是_Java读写Excel文件中数据的简便方法
  3. windows上双开微信代码
  4. 2020switch电信最快的dns_《2020switch电信最快的dns》电影_2020switch电信最快的dns正片免费观看-扬州人才服务网...
  5. 植被覆盖度的遥感估算
  6. 坚果nuts 加速 官网_坚果 R2 发布:骁龙 865、1 亿像素、双曲面屏,售价 4499 元...
  7. 互联网日报 | 360企业安全更名“政企安全”;B站获欢喜传媒独家外部播放权;银联发布首款数字银行卡...
  8. cmake gcc target specific option mismatch
  9. cad计算机绘图基础知识,CAD 计算机绘图基础课件.ppt
  10. c++filt看函数名