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. Tomcat服务器的下载与安装,修改端口号

    安装及简单配置Tomcat服务器: 1.登录www.apache.org 网站,之后点击Projects , 点击Project List,找到Tomcat. 2.点击Tomcat之后,之后进入Tom ...

  2. vue-cli中浏览器图标的配置

    在VUE全家桶项目里面,这里给大家提供了2种方案,进行浏览器图标的配置. a):先把图片准备好,放在static文件夹下,再找到根目录下的index.html文件,并打开,在HTML文档的<he ...

  3. [hdu5216]排序

    题意:给定两个长度为M的数组a,b,对于一个1-M的排列,不妨设为P,如果对任意0<=i<M,都有a[i] <= b[P[i]],那么称为一种合法情况,对于一种合法情况,对所有0&l ...

  4. java 8 stream、lambda表达式对list操作分组、过滤、求和、最值、排序、去重

    1.分组 通过groupingBy分组指定字段 list.stream().collect(Collectors.groupingBy(User::getSex)); 2.过滤 通过filter方法过 ...

  5. Android 编译系统

    1,Makefile编译方式 TARGET: PREREQUISITES COMMANDS 1,TARGET是需要生成的目标文件,PREREQUISTIES代表了目标所依赖的所有文件. 2,简单的Ma ...

  6. 「雕爷学编程」Arduino动手做(23)——矩形脉冲发生器

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  7. Maven 私服你应该不陌生吧,可你会用 Artifactory 搭建吗?

    JFrog Artifactory 是一个 Artifacts 仓库管理平台,它支持所有的主流打包格式.构建工具和持续集成(CI)服务器.它将所有二进制内容保存在一个单一位置并提供一个接口,这使得用户 ...

  8. 5.3 Go 匿名函数

    5.3 Go 匿名函数 Go支持匿名函数,顾名思义就是没名字的函数. 匿名函数一般用在,函数只运行一次,也可以多次调用. 匿名函数可以像普通变量一样被调用. 匿名函数由不带函数名字的函数声明与函数体组 ...

  9. 高效、可维护、组件化的CSS

    如何写出更加高效的CSS? 主要有以下四个关键点: 高效的CSS 可维护的CSS 组件化的CSS hack-free CSS 1.书写高效的CSS代码 * 使用 外联样式 替代行间 样式或者内嵌样式. ...

  10. 0515项目优化和List集合

    0515项目优化和List集合 1. 项目优化 1.1 分析当前情况 问题 数据存储是数组形式,数据类型明确.复用度较低. 需求 Student操作使用的代码,StudentManager想要操作考虑 ...