题目描述

  在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左(以自己为视角)或者向下移动一格,直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?
  
  

  例如,在上面的棋盘中,如果沿着带下画线的数字的线路(1、12、5、7、7、16、5),那么我们能拿到最大价值为53的礼物。

[牛客网刷题地址]无

思路分析

  1. 动态规划。我们先用递归的思路来分析。我们先定义第一个函数f(i,j)表示到达坐标为(i,j)的格子时能拿到的礼物总和的最大值。根据题目要求,我们有两种可能的途径到达坐标为(i,j)的格子:通过格子(i-1,j)或者(i,j-1)。所以f(i,j)= max(f(i-1,j), f(i,j-1)) + gift[i,j]。gift[i,j]表示坐标为(i,j)的格子里礼物的价值。
  2. 我们可以定义缓存数组来提高效率,避免递归带来的大量重复计算的问题。

测试用例

  1. 功能测试:多行多列的矩阵;一行或者一列的矩阵;只有一个数字的矩阵。
  2. 特殊输入测试:指向矩阵数组的指针为nullptr。

Java代码

  1. public class Offer047 {
  2. public static void main(String[] args) {
  3. test1();
  4. test2();
  5. test3();
  6. }
  7. public static int getMaxValue(int[][] values) {
  8. return Solution2(values);
  9. }
  10. /**
  11. * 用二位数组缓存
  12. * @param values
  13. * @return
  14. */
  15. private static int Solution1(int[][] values) {
  16. if(values==null || values.length<=0 || values[0].length<=0) {
  17. return 0;
  18. }
  19. int rows = values.length;
  20. int cols = values[0].length;
  21. int[][] maxValues = new int[rows][cols];
  22. for(int i=0;i<rows;i++) {
  23. for(int j=0;j<cols;j++) {
  24. int left = 0;
  25. int up = 0;
  26. if(i>0) {
  27. up = maxValues[i-1][j];
  28. }
  29. if(j>0) {
  30. left = maxValues[i][j-1];
  31. }
  32. maxValues[i][j] = Math.max(up,left)+values[i][j];
  33. }
  34. }
  35. return maxValues[rows-1][cols-1];
  36. }
  37. /**
  38. * 可以简化为一维数组
  39. * @param values
  40. * @return
  41. */
  42. private static int Solution2(int[][] values) {
  43. if(values==null || values.length<=0 || values[0].length<=0) {
  44. return 0;
  45. }
  46. int rows = values.length; //行
  47. int cols = values[0].length;//列
  48. int[] maxValue = new int[cols];
  49. for(int i=0;i<rows;i++) {
  50. for(int j=0;j<cols;j++) {
  51. int left = 0;
  52. int up = 0;
  53. if(i>0) {
  54. up = maxValue[j];
  55. }
  56. if(j>0) {
  57. left = maxValue[j-1];
  58. }
  59. maxValue[j] = Math.max(up,left)+values[i][j];
  60. }
  61. }
  62. return maxValue[cols-1];
  63. }
  64. private static void test1() {
  65. int[][] values = {{1,10,3,8},{12,2,9,6},{5,7,4,11},{3,7,16,5}};
  66. int maxValue = getMaxValue(values);
  67. System.out.println(maxValue);
  68. }
  69. private static void test2() {
  70. }
  71. private static void test3() {
  72. }
  73. }

代码链接

剑指Offer代码-Java

【Offer】[47] 【礼物的最大价值】的更多相关文章

  1. 力扣 - 剑指 Offer 47. 礼物的最大价值

    题目 剑指 Offer 47. 礼物的最大价值 思路1 因为是要求最大价值,而且只能移动下方或者右方,因此,每个位置的最大值就是本身的值加上上边 / 左边 中的最大值,然后每次遍历都可以复用上一次的值 ...

  2. 【Java】 剑指offer(47) 礼物的最大价值

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值( ...

  3. 每日一题 - 剑指 Offer 47. 礼物的最大价值

    题目信息 时间: 2019-07-02 题目链接:Leetcode tag:动态规划 难易程度:中等 题目描述: 在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0). ...

  4. 剑指 Offer 47. 礼物的最大价值

    题目描述 在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0).你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格.直到到达棋盘的右下角.给定一个棋盘及 ...

  5. 《剑指offer》面试题47. 礼物的最大价值

    问题描述 在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0).你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格.直到到达棋盘的右下角.给定一个棋盘及 ...

  6. 剑指offer——49礼物的最大价值

    题目描述 在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0).你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格,知道到达棋盘的右下角.给定一个棋盘及其上面 ...

  7. 《剑指offer》第四十七题(礼物的最大价值)

    // 面试题47:礼物的最大价值 // 题目:在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值 // (价值大于0).你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或 // 者向下 ...

  8. [剑指Offer]47-礼物的最大价值(DP)

    题目描述 在一个m*n的棋盘每个格有一个礼物,每个礼物有一定价值(>0).从棋盘左上角到右下角,只能向下或向右走,问能拿到的礼物最大价值. 解题思路 dp. 可将二维数组版优化为一维数组版. 代 ...

  9. acwing 60. 礼物的最大价值

    地址 https://www.acwing.com/problem/content/56/ 在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0). 你可以从棋盘的左上角开始拿 ...

随机推荐

  1. 记录eclipse中文出现空格宽度不一致的bug

    起因 不久前更新了 eclipse(2019-03) 版本:突然发现出现了,使用注释使用中出现的空格的间隔大小不一致的问题,具体可以看下图: 遇到这种问题简直逼不能忍,在网上搜一下解决方式: 谷歌 搜 ...

  2. 优雅的对象转换解决方案-MapStruct使用进阶(二)

    在前面, 介绍了 MapStruct 及其入门. 本文则是进一步的进阶. 在 MapStruct 生成对应的实现类的时候, 有如下的几个情景. 1 属性名称相同,则进行转化 在实现类的时候, 如果属性 ...

  3. Hadoop 系列(七)—— HDFS Java API

    一. 简介 想要使用 HDFS API,需要导入依赖 hadoop-client.如果是 CDH 版本的 Hadoop,还需要额外指明其仓库地址: <?xml version="1.0 ...

  4. 对vue中nextTick()的理解及使用场景说明

    异步更新队列: 首先我们要对vue的数据更新有一定理解: vue是依靠数据驱动视图更新的,该更新的过程是异步的. 即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新 ...

  5. .net core使用MQTT

    废话不多说,我们来直接实践…… 一.搭建mqtt控制台服务端 新建一个.net core控制台项目,然后使用Nuget添加MQTTnet包,我这里使用2.4版本,注意不同版本,代码写法不相同,如下图 ...

  6. @Value注解 和 @Data注解

    @Value注解 service层代码 @Service public class HelloServiceImpl implements HelloService { @Autowired priv ...

  7. ABAP:如何等待小数秒数

    WAIT UP TO x SECONDS. 和CALL FUNCTION 'ENQUE_SLEEP'都只能支持整数的秒数(如果是非整数,则四舍五入),如果要WAIT非整数的描述,可以如下写法:

  8. vue中的v-if和v-show的区别

    v-if和v-show的区别是前端面试中常问的基础知识点,v-if.v-show顾名思义就是用来判断视图层展示效果的.那么具体是怎么展示呢?v-if和v-show的区别又是什么呢? 首先我们可以来看一 ...

  9. 源码编译OpenJdk 8,Netbeans调试Java原子类在JVM中的实现(Ubuntu 16.04)

    一.前言 前一阵子比较好奇,想看到底层(虚拟机.汇编)怎么实现的java 并发那块. volatile是在汇编里加了lock前缀,因为volatile可以通过查看JIT编译器的汇编代码来看. 但是原子 ...

  10. [Spring cloud 一步步实现广告系统] 22. 广告系统回顾总结

    到目前为止,我们整个初级广告检索系统就初步开发完成了,我们来整体回顾一下我们的广告系统. 整个广告系统编码结构如下: mscx-ad 父模块 主要是为了方便我们项目的统一管理 mscx-ad-db 这 ...