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

  • 一、 题目
    • 1. 题目描述
    • 2. 原题链接
  • 二、 解题报告
    • 1. 思路分析
    • 2. 复杂度分析
    • 3. 代码实现
  • 三、 本题小结

一、 题目

1. 题目描述

  1. 摘樱桃

难度:困难

一个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。

2. 原题链接

链接: 741. 摘樱桃

二、 解题报告

1. 思路分析

 这题需要先做一个思路转换:原题要求去+回的路径,其实等同于两个人同时从左下角出发,走到右下角。我们的搜索按照这个思路来设计。
  • 思考两个人a,b同时从左上角出发,每一步同时进行,都往右或下移动,那么他们每个时刻一定在一条对角线上(可证明)。
  • 那么我们设计一个状态,dfs(x1,y1,x2,y2),代表a走到x1,y1且b走到x2,y2的时刻,两人总共能获得的樱桃最大数;
  • 显然这个状态可以从四个子状态转移而来,即每个人有两个可以来的位置,互相组合。
  • 深搜时,如果任何一个位置是非法的(越界或-1),那么我们返回-1(之所以不返回0是为了特殊判断没有连通)。
  • 他们一定同时回溯到原点,因此直接判断一个人在原点返回原点的樱桃数目。
  • 状态转移时,如果两个人在同一位置,这个位置的樱桃只能摘一次;否则,需要累计两人位置上的樱桃。
  • 特殊的,如果四个子状态都是-1,代表向上是搜索子状态没有通路,直接返回-1.
  • 最后判断如果是-1,则代表没有左上角到右下角的通路,返回0;否则返回ans。

2. 复杂度分析

最坏时间复杂度O(n3)

3. 代码实现

记忆化搜索

class Solution:def cherryPickup(self, grid: List[List[int]]) -> int:m,n = len(grid),len(grid[0])def in_bound(x,y):return 0<=x<m and 0<=y<n and grid[x][y] > -1 @cachedef dfs(x1,y1,x2,y2):if not in_bound(x1,y1) or not in_bound(x2,y2) :return -1if x1==0 and y1 == 0:return grid[0][0]ans = grid[x1][y1]if not (x1==x2 and y1 == y2):ans += grid[x2][y2]t = -1for a1,b1,a2,b2 in (x1-1,y1,x2-1,y2),(x1-1,y1,x2,y2-1),(x1,y1-1,x2-1,y2),(x1,y1-1,x2,y2-1):t = max(t,dfs(a1,b1,a2,b2))# print(a1,b1,a2,b2,dfs(a1,b1,a2,b2))if t == -1:return -1return ans + tans = dfs(n-1,n-1,n-1,n-1)# print(dfs(0,1,0,1))if ans == -1:return 0return ans

三、 本题小结

  1. 最难的就是一开始的思路转换,想到这个点后边就比较常规了。

[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解题报告] LCP 48. 无限棋局

    [LeetCode解题报告] LCP 48. 无限棋局 一. 题目 1. 题目描述 2. 原题链接 二. 解题报告 1. 思路分析 2. 复杂度分析 3. 代码实现 三. 本题小结 一. 题目 1. ...

  4. LeetCode解题报告汇总

    LeetCode解题报告: [LeetCode]1.Two Sum - Yoona - 博客频道 - CSDN.NET [LeetCode]2.Add Two Numbers - Yoona - 博客 ...

  5. 741.摘樱桃 动态规划

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

  6. [LeetCode解题报告] LCP 49. 环形闯关游戏

    [LeetCode解题报告] LCP 49. 环形闯关游戏 一. 题目 1. 题目描述 2. 原题链接 二. 解题报告 1. 思路分析 2. 复杂度分析 3. 代码实现 三. 本题小结 四. 参考链接 ...

  7. [LeetCode解题报告] 365. 水壶问题

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

  8. LeetCode 解题报告索引

    最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中......                        ...

  9. 力扣 741. 摘樱桃

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

最新文章

  1. android本地xml文件怎么打开,android 打开本地文件
  2. 火币网行情获取的websocket客户端
  3. java实现二分法递归_Java递归实现二分法
  4. apache2.4.9 开启path_info访问_如何通过SSH访问NAS?
  5. cocos2dx-3 addImageAsync陷阱
  6. CentOS7查看开放端口命令
  7. stl.find_if用法总结
  8. 病毒防疫管理系统基于VS2017 .netcore2.2
  9. 投影查询(2020-3-13)
  10. 2017年12月20日 内置对象
  11. xlsread服务器出现意外情况
  12. php 法定节假日接口,通过百度接口获取每一个月的工作和法定假日
  13. Hive数据仓库数据分析
  14. Opencv4android 眼睛追踪
  15. python中一个星号(*)与两个星号(**)的作用
  16. chrome跳转IE
  17. 余弦定理实现新闻自动分类算法
  18. tmc4361 闭环_TMC4361A是一种小型化、高性能的驱动步进电机的运动控制器
  19. 【超图+CESIUM】【基础API使用示例】50、超图|CESIUM - moveLeft\moveRight\moveForward\moveBackward实现运动中的碰撞检测效果
  20. 个人总结Android面试题目之二

热门文章

  1. matlab 分数阶 混沌分叉图,如何做出poincare 图或混沌分叉图
  2. linux 监控文件夹
  3. ip的正则表达式 完美版
  4. Solidity案例:经典众筹
  5. PADS Layout VX.2.2 - 导出 DXF 文件
  6. 圆锥曲线的部分趣事——圆的第二定义的传统几何证明方法、过圆锥曲线上点的切线方程以及该方程更广泛的意义
  7. Netty - 粘包和半包(上)
  8. Windows API一日一练(47)CreateSemaphore和ReleaseSemaphore函数
  9. vue使用qrcode-decoder解析二维码
  10. html页面的th标签合并,Table tr th td html表格标签