741. 摘樱桃

一个N x N的网格(grid) 代表了一块樱桃地,每个格子由以下三种数字的一种来表示:

0 表示这个格子是空的,所以你可以穿过它。

1 表示这个格子里装着一个樱桃,你可以摘到樱桃然后穿过它。

-1 表示这个格子里有荆棘,挡着你的路。

你的任务是在遵守下列规则的情况下,尽可能的摘到最多樱桃:

从位置 (0, 0) 出发,最后到达 (N-1, N-1) ,只能向下或向右走,并且只能穿越有效的格子(即只可以穿过值为0或者1的格子);

当到达 (N-1, N-1) 后,你要继续走,直到返回到 (0, 0) ,只能向上或向左走,并且只能穿越有效的格子;

当你经过一个格子且这个格子包含一个樱桃时,你将摘到樱桃并且这个格子会变成空的(值变为0);

如果在 (0, 0) 和 (N-1, N-1) 之间不存在一条可经过的路径,则没有任何一个樱桃能被摘到。

示例 1:

输入: grid =

[[0, 1, -1],

[1, 0, -1],

[1, 1, 1]]

输出: 5

解释:

玩家从(0,0)点出发,经过了向下走,向下走,向右走,向右走,到达了点(2, 2)。

在这趟单程中,总共摘到了4颗樱桃,矩阵变成了[[0,1,-1],[0,0,-1],[0,0,0]]。

接着,这名玩家向左走,向上走,向上走,向左走,返回了起始点,又摘到了1颗樱桃。

在旅程中,总共摘到了5颗樱桃,这是可以摘到的最大值了。

说明:

grid 是一个 N * N 的二维数组,N的取值范围是1 <= N <= 50。

每一个 grid[i][j] 都是集合 {-1, 0, 1}其中的一个数。

可以保证起点 grid[0][0] 和终点 grid[N-1][N-1] 的值都不会是 -1。

PS:

这道题可以转换一下变成: 我一下走两个位置并且只能往下走或者往右走

既然这么走,我的这一个位置的x+y就会等于另一个位置的x+y

或者用数组做,保存坐标

class Solution {
public int cherryPickup(int[][] grid) {
int m = grid.length;
int memo[][][] = new int[m][m][m];
for (int[][] layer: memo)
for (int[] row: layer)
Arrays.fill(row, Integer.MIN_VALUE);
int res = dp(grid,memo,0,0,0);
return Math.max(res,0);
} public int dp(int[][] grid,int[][][] memo,int r1,int c1, int r2){
int c2 =r1+c1-r2;
if(r1==grid.length||r2==grid.length||c1==grid.length||c2==grid.length||grid[r1][c1]==-1||grid[r2][c2]==-1){
return -99999;
}
if(r1==grid.length-1&&c1==grid.length-1){
return grid[r1][c1];
}
if(memo[r1][c1][r2]!=Integer.MIN_VALUE){
return memo[r1][c1][r2];
}
int ans = 0;
if(r1!=r2){
ans = max(dp(grid,memo,r1+1,c1,r2+1),dp(grid,memo,r1+1,c1,r2),dp(grid,memo,r1,c1+1,r2+1),dp(grid,memo,r1,c1+1,r2) ) + grid[r1][c1] + grid[r2][c2];
}else{
ans = max(dp(grid,memo,r1+1,c1,r2+1),dp(grid,memo,r1+1,c1,r2),dp(grid,memo,r1,c1+1,r2+1),dp(grid,memo,r1,c1+1,r2)) + grid[r1][c1];
}
memo[r1][c1][r2] = ans;
return ans;
} public int max(int a, int b,int c,int d){
a = Math.max(a,b);
a = Math.max(a,c);
a = Math.max(a,d);
return a;
}
}
class Solution {
public int cherryPickup(int[][] grid) {
int N = grid.length;
int[][] dp = new int[N + 1][N + 1];
for (int[] row : dp) {
Arrays.fill(row, Integer.MIN_VALUE);//使用了N+1,因此边界值也设置为MIN_VALUE
}
dp[N - 1][N - 1] = grid[N - 1][N - 1]; //sum表示一共要走的步数,也就是所谓的递增就好,不需要使用三维数组k,当前走第k步,一共要走2*N-2步(n-1)*2,下标的话就是2N-3
for (int sum = 2 * N - 3; sum >= 0; sum--) {
for (int i1 = Math.max(0, sum - N + 1); i1 <= Math.min(N - 1, sum); i1++) {//倒序
for (int i2 = i1; i2 <= Math.min(N - 1, sum); i2++) {
int j1 = sum - i1;
int j2 = sum - i2;
if (grid[i1][j1] == -1 || grid[i2][j2] == -1) {
dp[i1][i2] = Integer.MIN_VALUE;
} else {
if (i1 != i2 || j1 != j2) {
//不重合在同一个点,则获取的最大值=A的格子+B的格子+AB往哪个方向走,也就是上一个状态是怎么来得,
dp[i1][i2] = grid[i1][j1] + grid[i2][j2] + Math.max(Math.max(dp[i1][i2 + 1], dp[i1 + 1][i2]), Math.max(dp[i1][i2], dp[i1 + 1][i2 + 1]));
} else {
dp[i1][i2] = grid[i1][j1] + Math.max(Math.max(dp[i1][i2 + 1], dp[i1 + 1][i2]), Math.max(dp[i1][i2], dp[i1 + 1][i2 + 1]));
} }
}
}
}
return Math.max(0,dp[0][0]); }
}

Java实现 LeetCode 741 摘樱桃(DFS || 递推 || 传纸条)的更多相关文章

  1. 每日一题 LeetCode 486. 预测赢家 【递推】【前缀和】【动态规划】

    题目链接 https://leetcode-cn.com/problems/predict-the-winner/ 题目说明 题解 主要方法:递推:动态规划:前缀和 解释说明: 求前缀和 pre_nu ...

  2. 每日一题 LeetCode 491. 递增子序列 【递推】【递增子序列】【动态规划】

    题目链接 https://leetcode-cn.com/problems/increasing-subsequences/ 题目说明 题解 主要方法:递推:动态规划 解释说明: 数据表示:观察数据范 ...

  3. Java实现 LeetCode 529 扫雷游戏(DFS)

    529. 扫雷游戏 让我们一起来玩扫雷游戏! 给定一个代表游戏板的二维字符矩阵. 'M' 代表一个未挖出的地雷,'E' 代表一个未挖出的空方块,'B' 代表没有相邻(上,下,左,右,和所有4个对角线) ...

  4. hdu3555(数位DP dfs/递推)

    Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  5. Java实现 蓝桥杯VIP 算法训练 步与血(递推 || DFS)

    试题 算法训练 步与血 问题描述 有n*n的方格,其中有m个障碍,第i个障碍会消耗你p[i]点血.初始你有C点血,你需要从(1,1)到(n,n),并保证血量大于0,求最小步数. 输入格式 第一行3个整 ...

  6. Java实现 LeetCode 673 最长递增子序列的个数(递推)

    673. 最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, ...

  7. Java实现 LeetCode 639解码方法 2(递推)

    639. 解码方法 2 一条包含字母 A-Z 的消息通过以下的方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 除了上述的条件以外,现在加密字符串可以 ...

  8. Java for LeetCode 216 Combination Sum III

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  9. Java for LeetCode 212 Word Search II

    Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...

随机推荐

  1. Istio的流量管理(概念)(istio 系列二)

    Istio的流量管理(概念) 目录 Istio的流量管理(概念) 概述 Virtual services 为什么使用virtual service Virtual services举例 hosts字段 ...

  2. 一阶RC低通滤波器详解(仿真+matlab+C语言实现)

    文章目录 1 预备知识 2 simulink 仿真 3 simulink 运行结果 4 matlab实现 5 matlab运行结果 6 C语言实现 7 C语言运行结果 如果本文帮到了你,帮忙点个赞: ...

  3. STM32 串口USART DMA方式发送接收数据

    硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 头文件 USART3_DR的地址 DMA的通道 DMA的中断 USART接收回调函数 头 ...

  4. [hdu4292]最大流,拆点

    题意:给定每个人所喜欢的食物和饮料种类以及每种食物和饮料的数量,一个人需要一种食物和一种饮料(数量为1即可),问最多满足多少人的需要 思路:由于食物和饮料对于人来说需要同时满足,它们是“与”的关系,所 ...

  5. springData表关系:一对一

    一.编写两个实体类 1.一对一关系实现:a:使用外键关联 b:使用主键关联,两个表的主键相同 2.外键方案:配置关联关系:两个实体类互相关联,并且在关联的属性上添加一个@OneToOne代表一个对一个 ...

  6. 关于 Blob

    博客地址:https://ainyi.com/88 对于 Blob,前端开发中可能比较少遇到:数据库中可使用 Blob 概念,例如 Mysql 存储二进制数据的类型就是 Blob,也就是说图片可存储于 ...

  7. 一文带你学会国产加密算法SM4的vue实现方案

    前言 上篇文章我们介绍了国产SM4加密算法的后端java实现方案.没有看过的小伙伴可以看一下这篇文章. https://www.cnblogs.com/jichi/p/12907453.html 本篇 ...

  8. Spark aggregateByKey函数

    aggregateByKey与aggregate类似,都是进行两次聚合,不同的是后者只对分区有效,前者对分区中key进一步细分 def aggregateByKey[U: ClassTag](zero ...

  9. 从模块化到认识Babel

    转载自:https://www.cnblogs.com/qcloud1001/p/10167756.html https://blog.csdn.net/a250758092/article/deta ...

  10. JDK 安装与环境变量配置

    JDK官网下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 1.下载jd ...