https://leetcode.com/problems/cherry-pickup/description/

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.

思路

解答给出的第一种方法时贪心,但是并不是正确答案,正确解法还是万能的dp。

在 t 个steps后,我们到的位置 (r, c),有 r+c=t 。如果有两个人在位置在 t 个steps后在位置 positions (r1, c1) and (r2, c2) 上,那么有 r2 = r1 + c1 - c2。 这意味着变量r1, c1, c2唯一决定了两个都走了r1 + c1 number of steps人的位置。这是我们动态规划思想的基础。

自顶向下的dp:

Let dp[r1][c1][c2] be the most number of cherries obtained by two people starting at (r1, c1) and (r2, c2)and walking towards (N-1, N-1) picking up cherries, where r2 = r1+c1-c2.

If grid[r1][c1] and grid[r2][c2] are not thorns, then the value of dp[r1][c1][c2] is (grid[r1][c1] + grid[r2][c2]), plus the maximum of dp[r1+1][c1][c2]dp[r1][c1+1][c2]dp[r1+1][c1][c2+1]dp[r1][c1+1][c2+1] as appropriate. We should also be careful to not double count in case (r1, c1) == (r2, c2).

Why did we say it was the maximum of dp[r+1][c1][c2] etc.? It corresponds to the 4 possibilities for person 1 and 2 moving down and right:

  • Person 1 down and person 2 down: dp[r1+1][c1][c2];
  • Person 1 right and person 2 down: dp[r1][c1+1][c2];
  • Person 1 down and person 2 right: dp[r1+1][c1][c2+1];
  • Person 1 right and person 2 right: dp[r1][c1+1][c2+1];

要点:1. 将题目中要求的从起始到末尾在返回起始点,等价为二个人同时从起点出发去重点。

      2. 一个三维的dp数组,标记了两个人的位置,以及当前最优解

   3. 子问题之间的关系,要避免重复计算。

代码

class Solution {
int[][][] memo;
int[][] grid;
int N;
public int cherryPickup(int[][] grid) {
this.grid = grid;
N = grid.length;
memo = new int[N][N][N];
for (int[][] layer: memo)
for (int[] row: layer)
Arrays.fill(row, Integer.MIN_VALUE);
return Math.max(0, dp(0, 0, 0));
}
public int dp(int r1, int c1, int c2) {
int r2 = r1 + c1 - c2;
if (N == r1 || N == r2 || N == c1 || N == c2 ||
grid[r1][c1] == -1 || grid[r2][c2] == -1) { //到达边界或者遇到阻碍
return -999999;
} else if (r1 == N-1 && c1 == N-1) {
return grid[r1][c1];
} else if (memo[r1][c1][c2] != Integer.MIN_VALUE) { // 如果这个位置计算过了则不需要再次计算
return memo[r1][c1][c2];
} else {
int ans = grid[r1][c1];
if (c1 != c2) ans += grid[r2][c2];
ans += Math.max(Math.max(dp(r1, c1+1, c2+1), dp(r1+1, c1, c2+1)),
Math.max(dp(r1, c1+1, c2), dp(r1+1, c1, c2)));
memo[r1][c1][c2] = ans;
return ans;
}
}
}

上面是自顶向下的dp。另一中是自低向上的dp:

At time t, let dp[c1][c2] be the most cherries that we can pick up for two people going from (0, 0) to (r1, c1)and (0, 0) to (r2, c2), where r1 = t-c1, r2 = t-c2. Our dynamic program proceeds similarly to Approach 

class Solution {
public int cherryPickup(int[][] grid) {
int N = grid.length;
int[][] dp = new int[N][N];
for (int[] row: dp) Arrays.fill(row, Integer.MIN_VALUE);
dp[0][0] = grid[0][0]; for (int t = 1; t <= 2*N - 2; ++t) {
int[][] dp2 = new int[N][N];
for (int[] row: dp2) Arrays.fill(row, Integer.MIN_VALUE); for (int i = Math.max(0, t-(N-1)); i <= Math.min(N-1, t); ++i) {
for (int j = Math.max(0, t-(N-1)); j <= Math.min(N-1, t); ++j) {
if (grid[i][t-i] == -1 || grid[j][t-j] == -1) continue;
int val = grid[i][t-i];
if (i != j) val += grid[j][t-j];
for (int pi = i-1; pi <= i; ++pi)
for (int pj = j-1; pj <= j; ++pj)
if (pi >= 0 && pj >= 0)
dp2[i][j] = Math.max(dp2[i][j], dp[pi][pj] + val);
}
}
dp = dp2;
}
return Math.max(0, dp[N-1][N-1]);
}
}

LeetCode741. Cherry Pickup的更多相关文章

  1. [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 ...

  2. [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 ...

  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. 741. Cherry Pickup

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

  5. LeetCode 741. Cherry Pickup

    原题链接在这里:https://leetcode.com/problems/cherry-pickup/ 题目: 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. [LeetCode] Dungeon Game 地牢游戏

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  8. [LeetCode] Minimum Path Sum 最小路径和

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  9. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

随机推荐

  1. Linux下chkconfig命令详解--(启动或停止)和查询系统服务的运行级信息

    chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...

  2. UTF-8和GBK编码之间的区别(页面编码、数据库编码区别)以及在实际项目中的应用

    第一节:UTF-8和GBK编码概述 UTF-8 (8-bit Unicode Transformation Format) 是一种针对Unicode的可变长度字符编码,又称万国码,它包含全世界所有国家 ...

  3. 【线段树】【CF19D】 Points

    传送门 Description 在一个笛卡尔坐标系中,定义三种操作: \(add(x,y)\),将点\((x,y)\)标记在坐标系上 \(find(x,y)\),查询点\((x,y)\)严格右上方中, ...

  4. STL源码分析-algorithm

    http://note.youdao.com/noteshare?id=8b3473983e4c8d8eee32544708633f79

  5. animatescroll.min.js ~~~~ jq滚动效果 优化target自定义方法

    $(".meun>div[name='meun_nav']>a").eq(1).on("click",function(){ $("bod ...

  6. 前端PHP入门-035-Session的实例

      登陆例子:(请注意一定要自己敲一遍,不要CV大法) 首先上一下成果图,激起同学们写的欲望,登录页如下: 点击登陆之后如下: 说明哦了,么问题.接下来自己实现一下. 首先数据库信息: 新建一个名为 ...

  7. [LeetCode] 数学计算模拟类问题:加法,除法和幂,注意越界问题。题 剑指Offer,Pow(x, n) ,Divide Two Integers

    引言 数学计算的模拟类题目,往往是要求实现某种计算(比如两数相除),实现的过程中会有所限定,比如不允许乘法等等. 这类题目首先要注意计算过程中本身的特殊情况.比如求相除,则必须首先反映过来除数不能为0 ...

  8. NOIP模拟6

    期望得分:100+100+100=300 实际得分:0+100+90=190 T1 superman 二分给每条边加多少,判断是否存在负环 #include<queue> #include ...

  9. UVA 1575 Factors

    https://vjudge.net/problem/UVA-1575 题意: 令f(k)=n 表示 有n种方式,可以把正整数k表示成几个数的乘积的形式. 例 10=2*5=5*2,所以f(10)=2 ...

  10. HDU 1299 基础数论 分解

    给一个数n问有多少种x,y的组合使$\frac{1}{x}+\frac{1}{y}=\frac{1}{n},x<=y$满足,设y = k + n,代入得到$x = \frac{n^2}{k} + ...