LeetCode741. Cherry Pickup
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 anN
byN
2D array, with1 <= 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的更多相关文章
- [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 ...
- [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 ...
- [LeetCode] Cherry Pickup 捡樱桃
In a N x N grid representing a field of cherries, each cell is one of three possible integers. 0 mea ...
- 741. Cherry Pickup
In a N x N grid representing a field of cherries, each cell is one of three possible integers. 0 mea ...
- LeetCode 741. Cherry Pickup
原题链接在这里:https://leetcode.com/problems/cherry-pickup/ 题目: In a N x N grid representing a field of che ...
- 动态规划-Cherry Pickup
2020-02-03 17:46:04 问题描述: 问题求解: 非常好的题目,和two thumb其实非常类似,但是还是有个一点区别,就是本题要求最后要到达(n - 1, n - 1),只有到达了(n ...
- [LeetCode] Dungeon Game 地牢游戏
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- [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 ...
- Swift LeetCode 目录 | Catalog
请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift 说明:题目中含有$符号则为付费题目. 如 ...
随机推荐
- Unity3D for VR 学习(2): 暴风魔镜框架探索
学习一个新技术,有三个法宝: 法宝1: 掌握厂家提供的用户API手册 法宝2: 掌握厂家提供的demo样例 法宝3:<每个研发人员都应树立的一个demo模式> 故,学习魔镜4技术,亦如是也 ...
- hdu1693 Eat the Trees 【插头dp】
题目链接 hdu1693 题解 插头\(dp\) 特点:范围小,网格图,连通性 轮廓线:已决策点和未决策点的分界线 插头:存在于网格之间,表示着网格建的信息,此题中表示两个网格间是否连边 状态表示:当 ...
- 洛谷U14667 肝活动【比赛】 【状压dp】
题目描述 Yume 最近在玩一个名为<LoveLive! School idol festival>的音乐游戏.他之所以喜欢上这个游戏,是因为这个游戏对非洲人十分友好,即便你脸黑到抽不出好 ...
- Spring切面之一
为什么要使用AOP,在编写程序的时候,除了不必关心依赖的组件如何实现,在实际开发过程中,还需要将程序中涉及的公共问题集中解决.AOP是Aspect-Oriented Programming的简称,意思 ...
- PID控制算法的c语言实现十二 模糊PID的参数整定
这几天一直在考虑如何能够把这一节的内容说清楚,对于PID而言应用并没有多大难度,按照基本的算法设计思路和成熟的参数整定方法,就算是没有经过特殊训练和培训的人,也能够在较短的时间内容学会使用PID算法. ...
- BNU-2017.7.3排位赛1总结
比赛链接:https://www.bnuoj.com/v3/contest_show.php?cid=9146#info A题 国际象棋棋盘,黑白相间染色. B题 最大值只取决于每个连通块的大小,一个 ...
- mac 的全文搜索
grep -Rni "view.proptypes.style" * 需要切换到要搜索的目录在运行
- 数据压缩算法之哈夫曼编码(HUFFMAN)的实现
HUFFMAN编码可以很有效的压缩数据,通常可以压缩20%到90%的空间(算法导论).具体的压缩率取决于数据的特性(词频).如果采取标准的语料库进行编码,一般可以得到比较满意的编码结果(对不同文件产生 ...
- [DeeplearningAI笔记]序列模型3.3集束搜索
5.3序列模型与注意力机制 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.3 集束搜索Beam Search 对于机器翻译来说,给定输入的句子,会返回一个随机的英语翻译结果,但是你想要一 ...
- 源码包安装 NGINX时候遇到的错误以及解决办法!
最近跟一个公司合作,要把我们的应用安装在他们的服务器上,不过问题来了.他们为了他们自己服务器安全,不给我们root权限,只给了我们普通用户权限,所有的程序都要装在规定的路径里,限制可不少.没办法装吧~ ...