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. 什么是maven,jar包的查找过程?

    1.什么是maven? Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件. 2.什么是项目管理工具? 就是SVN.对于SVN的介绍见我的上一篇博客 ...

  2. spring框架之数组,集合(List,Set,Map),Properties等的注入

    先编写User类: package com.huida.demo4; import java.util.Arrays; import java.util.List; import java.util. ...

  3. Golang之Mysql操作

    话说当年武大郎对着电脑一顿噼里啪啦,,,对mysql增删改查 增加insert package main import ( "fmt" "github.com/jmoir ...

  4. Qt中使用python--Hello Python!

    step1:install Python (version 2.7 or higher): step2:The configuration is as follows: 1.create qt con ...

  5. Linux 添加硬盘

    一.简介 本文介绍为Linux 添加硬盘的基本方法,同时适用于为虚拟机添加硬盘的情况.   二.添加小于2T的硬盘 1)分区 fdisk /dev/hda 2)建立文件系统 3)设置开机自动挂载磁盘 ...

  6. Git 初始状操作指引

    You have an empty repository To get started you will need to run these commands in your terminal. Ne ...

  7. Jmeter Ant Task如果报告中有错误,在邮件内容里面直接显示出来 系列2

    由于部门有多个项目,将自动化测试框架运用于多个项目时,希望针对每个项目修改的东西越少越好,为此,做如下修改: D:\apache-jmeter-2.7\extras\jmeter-results-de ...

  8. 2018.08.15 bzoj3747: [POI2015]Kinoman(线段树)

    传送门 简单题. 先不管时间复杂度看看怎么做. 对于一段区间[l,r],如果从右端加入一个数a[r+1],对这个区间有什么影响?显然如果区间中已经有了a[r+1]这个数就会产生-a[i+1]的影响,否 ...

  9. 微信小程序 获取用户openid

    1,可以在小程序app.js入口文件中放入登录代码 wx.login({ success: res => { // 登录注册接口 if (res.code) { // 调用服务端登录接口,发送 ...

  10. web前端技术合集

    视频课程包含: 微服务精品课程包含:Ajax和Jquery基础入门视频.ajax教程.css视频教程.JQuery视频教程.MUI快速混合APP开发-视频.vuejs教程.极客学院HTML5全套教程. ...