zoukankan      html  css  js  c++  java
  • 【Offer】[47] 【礼物的最大价值】

    题目描述

      在一个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代码

    public class Offer047 {
        public static void main(String[] args) {
            test1();
            test2();
            test3();
            
        }
    
        public static int getMaxValue(int[][] values) {
            return Solution2(values);
        }
    
        /**
         * 用二位数组缓存
         * @param values
         * @return
         */
        private static int Solution1(int[][] values) {
            if(values==null || values.length<=0 || values[0].length<=0) {
                return 0;
            }
            int rows = values.length;
            int cols = values[0].length;
            int[][] maxValues = new int[rows][cols];
            for(int i=0;i<rows;i++) {
                for(int j=0;j<cols;j++) {
                    int left = 0;
                    int up = 0;
                    if(i>0) {
                        up = maxValues[i-1][j];
                    }
                    if(j>0) {
                        left = maxValues[i][j-1];
                    }
                    maxValues[i][j] = Math.max(up,left)+values[i][j];
                }
            }
            
            return maxValues[rows-1][cols-1];
        }
    
        /**
         * 可以简化为一维数组
         * @param values
         * @return
         */
        private static int Solution2(int[][] values) {
            if(values==null || values.length<=0 || values[0].length<=0) {
                return 0;
            }
            int rows = values.length; //行
            int cols = values[0].length;//列
            
            int[] maxValue = new int[cols];
            for(int i=0;i<rows;i++) {
                for(int j=0;j<cols;j++) {
                    int left = 0;
                    int up = 0;
                    if(i>0) {
                        up = maxValue[j];
                    }
                    if(j>0) {
                        left = maxValue[j-1];
                    }
                    maxValue[j] = Math.max(up,left)+values[i][j];
                }
            }
            return maxValue[cols-1];
        }
    
        private static void test1() {
            int[][] values = {{1,10,3,8},{12,2,9,6},{5,7,4,11},{3,7,16,5}};
            int maxValue = getMaxValue(values);
            System.out.println(maxValue);
        }
    
        private static void test2() {
    
        }
        private static void test3() {
    
        }
    }
    

    代码链接

    剑指Offer代码-Java

  • 相关阅读:
    将jar包安装到本地repository中,---以greenplum.jar举例
    推荐系统学习起步
    代理模式详解:静态代理、JDK动态代理与Cglib动态代理
    MyBatis(四):自定义持久层框架优化
    MyBatis(二):自定义持久层框架思路分析
    MyBatis(一):JDBC使用存在的问题
    PHP编程趣事:能喝几瓶啤酒?
    Linux下的两个经典宏定义
    C/C++中常用的字符串处理函数和内存字符串函数
    设计模式之适配器模式(Adapter Pattern)C++实现
  • 原文地址:https://www.cnblogs.com/haoworld/p/offer47-li-wu-de-zui-da-jia-zhi.html
Copyright © 2011-2022 走看看