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. laravel表单图片上传

    1.视图 2.控制器

  2. send发送一次buffer

    发送的字符串后面添加:\r\n 结束标志 否则发送1024或者程序接收默认的字节数 #include <stdio.h> #include <stdlib.h> #includ ...

  3. eclipse缓存太重,新手最容易中招

    有4种方法,从上到下清理:

  4. Selenium安装中的一些问题及解决办法-软硕1703班3组整理分享

    非常感谢软件工程硕士1703班3组同学的热心,他们将安装Selenium过程中踩过的坑替大家填上了.希望还没有来得及踩坑的,或者掉进坑里还没爬出来的小组,能顺利跨过去这个安装的坑. 如下是原文. Se ...

  5. Java知识系列 -- 反射

    原理 要想理解 Java 反射,首先要弄清类的加载过程. 比如这行代码 Person p = new Person();. 我们想要创建一个 Person 对象,并用 p 作为对象的引用. 在 Jav ...

  6. 2018.10.17 NOIP模拟 发电机(概率dp)

    传送门 考试空间开大了爆零不然只有30分爆栈? 话说这题真的坑1e7没法写dfsdfsdfs 其实很好推式子. 考虑每个点安一个发动机的概率,推一波式子做个等比数列求和什么的可以证明出来是严格的1si ...

  7. matplotlib在MAC系统下中文字体显示问题

    最近想把部分python数据分析的代码从win系统迁移到MAC上,有部分图片上涉及中文显示,迁移到MAC上warning: UserWarning: findfont: Font family [u' ...

  8. python将字典中的数据保存到文件中

    d = {'a':'aaa','b':'bbb'}s = str(d)f = open('dict.txt','w')f.writelines(s)f.close()

  9. SpringMvc中controller之间的方法调用

    方法一, return new ModelAndView("redirect:"+新地址); 方法二, response.sendRedirect(新地址); return nul ...

  10. android中Actionbar详解

    1.什么是Action BarAction Bar被认为是新版Android系统中最重要的交互元素,在程序运行中一直置于顶部,主要起到的作用在于:1)突出显示一些重要操作(如“最新”.“搜索”等)2) ...