In a N x N grid representing a field of cherries, each cell is one of three possible integers.

  • 0 means the cell is empty, so you can pass through;
  • 1 means the cell contains a cherry, that you can pick up and pass through;
  • -1 means the cell contains a thorn that blocks your way.

Your task is to collect maximum number of cherries possible by following the rules below:

  • Starting at the position (0, 0) and reaching (N-1, N-1) by moving right or down through valid path cells (cells with value 0 or 1);
  • After reaching (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells;
  • When passing through a path cell containing a cherry, you pick it up and the cell becomes an empty cell (0);
  • If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected.

Example 1:

Input: grid =
[[0, 1, -1],
[1, 0, -1],
[1, 1, 1]]
Output: 5
Explanation:
The player started at (0, 0) and went down, down, right right to reach (2, 2).
4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]].
Then, the player went left, up, up, left to return home, picking up one more cherry.
The total number of cherries picked up is 5, and this is the maximum possible.

Note:

    • grid is an N by N 2D array, with 1 <= N <= 50.
    • Each grid[i][j] is an integer in the set {-1, 0, 1}.
    • It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1.

Approach#1: DFS + Memory. [C++]

class Solution {
public:
int cherryPickup(vector<vector<int>>& grid) {
int n = grid.size();
grid_ = &grid;
memo = vector<vector<vector<int>>>(n+1, vector<vector<int>>(n+1, vector<int>(n+1, INT_MIN)));
return max(0, dp(n-1, n-1, n-1));
} private:
vector<vector<vector<int>>> memo;
vector<vector<int>> *grid_;
int dp(int x1, int y1, int x2) {
int y2 = x1 + y1 - x2;
if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0) return -1;
if ((*grid_)[x1][y1] < 0 || (*grid_)[x2][y2] < 0) return -1;
if (x1 == 0 && y1 == 0) return (*grid_)[x1][y1];
if (memo[x1][y1][x2] != INT_MIN) return memo[x1][y1][x2];
int tmp = max(max(dp(x1-1, y1, x2-1), dp(x1, y1-1, x2)),
max(dp(x1, y1-1, x2-1), dp(x1-1, y1, x2)));
if (tmp < 0) return memo[x1][y1][x2] = -1;
tmp += (*grid_)[x1][y1];
if (x1 != x2) tmp += (*grid_)[x2][y2];
return memo[x1][y1][x2] = tmp;
}
};

  

Analysis:

Key observation: (0, 0) to (n-1, n-1) to (0, 0) is the same as (n-1, n-1) to (0, 0) twice

Two people starting from (n-1, n-1) and go to (0, 0).

They move one step (left or up) at a time simultaneously. And pick up the cherry within the grid (if there is one).

if they ended up at the same grid with a cherry. Only one of them can pick up it.

x1, y1, x2 to represent a state y2 can be computed: y2 = x1 + y1 - x2.

dp(x1, y1, x2) computes the max cherries if start from {(x1, y1), (x2, y2)} to (0, 0), which is a recursive function.

Since two people move independently, there are 4 subproblems: (left, left), (left, up), (up, left), (left, up). Finally, we have:

dp(x1, y1, x2) = g[y1][x1] + g[y2][x2] + max(dp(x1-1, y1, x2-1), dp(x1, y1-1, x2-1), dp(x1-1, y1, x2), dp(x1, y1-1, x2))

Time complexity: O(n^3)

Space complexity: O(n^3)

Reference:

http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-741-cherry-pickup/

741. Cherry Pickup的更多相关文章

  1. [LeetCode] 741. Cherry Pickup 捡樱桃

    In a N x N grid representing a field of cherries, each cell is one of three possible integers. 0 mea ...

  2. LeetCode 741. Cherry Pickup

    原题链接在这里:https://leetcode.com/problems/cherry-pickup/ 题目: In a N x N grid representing a field of che ...

  3. [LeetCode] Cherry Pickup 捡樱桃

    In a N x N grid representing a field of cherries, each cell is one of three possible integers. 0 mea ...

  4. [Swift]LeetCode741. 摘樱桃 | Cherry Pickup

    In a N x N grid representing a field of cherries, each cell is one of three possible integers. 0 mea ...

  5. LeetCode741. Cherry Pickup

    https://leetcode.com/problems/cherry-pickup/description/ In a N x N grid representing a field of che ...

  6. 动态规划-Cherry Pickup

    2020-02-03 17:46:04 问题描述: 问题求解: 非常好的题目,和two thumb其实非常类似,但是还是有个一点区别,就是本题要求最后要到达(n - 1, n - 1),只有到达了(n ...

  7. 动态规划Dynamic Programming

    动态规划Dynamic Programming code教你做人:DP其实不算是一种算法,而是一种思想/思路,分阶段决策的思路 理解动态规划: 递归与动态规划的联系与区别 -> 记忆化搜索 -& ...

  8. 矩形最小路径和 · Minimum Path Sum

    [抄题]: 给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径. [思维问题]: [一句话思路]: 和数字三角形基本相同 [输入量]:空: 正常情况:特大:特小:程序里 ...

  9. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

随机推荐

  1. js和jquery获取span里面的值

    JQ和Js获取span标签的内容 html: 1 <span id="content">‘我是span标签的内容’</span> javascript获取: ...

  2. 转载 springboot 配置读取

    前言:了解过spring-Boot这个技术的,应该知道Spring-Boot的核心配置文件application.properties,当然也可以通过注解自定义配置文件**.properties的信息 ...

  3. BZOJ1222 [HNOI2001]产品加工 - 动态规划- 背包

    题解 怎么看都不像是个背包,直到我看了题解→_→, 第一次碰到这么奇怪的背包= = 定一个滚动数组$F_i$, $i$表示机器$a$用了$i$的时间, $F_i$表示机器$b$用了$F_i$的时间, ...

  4. c++ 博客资源

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  5. KBMMW 4.81.00 发布

    这次更新的速度非常快. 4.81.00 May 9 2015 Important notes (changes that may break existing code) ============== ...

  6. 2018.09.27 hdu4507吉哥系列故事——恨7不成妻(数位dp)

    传送门 一道比较综合的数位dp. 维护三个值:[L,R][L,R][L,R] 区间中与7无关的数的数量,与7无关的数之和,与7无关的数的的平方和. 然后可以用第一个值推第二个,第一个和第二个值推第三个 ...

  7. Flex box 弹性盒子布局

    display: -webkit-flex 标识使用弹性布局 flex: num  占容器的比例   Flex等比划分 导航1 : Flex :1;  导航2  Flex: 2;     ————&g ...

  8. B样条参数曲线学习(1)

    B样条参数曲线学习 Bezier曲线有许多优越性,但有两点不足: (1) 特征多边形的顶点个数决定了Bezier曲线的阶次,并且在阶次较大时,特征多边形对曲线的控制将会减弱: (2) Bezier曲线 ...

  9. 基于MATLAB的均值滤波算法实现

    在图像采集和生成中会不可避免的引入噪声,图像噪声是指存在于图像数据中的不必要的或多余的干扰信息,这对我们对图像信息的提取造成干扰,所以要进行去噪声处理,常见的去除噪声的方法有均值滤波.中值滤波.高斯滤 ...

  10. hdu 5063 操作逆推+mul每次要*2%(modo - 1)

    http://acm.hdu.edu.cn/showproblem.php?pid=5063 只有50个询问,50个操作逆推回去即可,注意mul每次要*2%(modo - 1)因为是指数! #incl ...