剑指offer 学习笔记 礼物的最大价值

2023-11-04

面试题47:礼物的最大价值。在一个mxn的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格,直到到达棋盘的右下角。给定一个棋盘和上面的礼物,请计算你最多能拿到多少价值的礼物。

这是一个典型的能用动态规划解决的问题,先用递归思路来分析,我们先定义第一个函数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]。我们用递归分析问题,但由于有大量的重复计算,基于循环从底向上计算效率要高很多,为了缓存中间的计算结果,我们需要一个辅助的二维数组,以下代码以下图中棋盘为例,下划线元素路径为最大价值路径,最大价值为53:
在这里插入图片描述

#include <iostream>
using namespace std;

int GetMaxValue(const int* values, int rows, int cols) {
    if (values == nullptr || rows < 1 || cols < 1) {
        return 0;
    }

    int** res = new int* [rows]();    // 加上圆括号相当于值初始化(将res中所有指针值初始化为空指针)堆内存,否则其中内容是未定义的
    for (int i = 0; i < rows; ++i) {
        res[i] = new int[cols]();    // 加上圆括号相当于值初始化(将res[i]中所有元素值初始化为0)堆内存,否则其中内容是未定义的
    }

    for (int row = 0; row < rows; ++row) {
        for (int col = 0; col < cols; ++col) {
            int up = 0;
            if (row != 0) {
                up = res[row - 1][col];
            }

            int left = 0;
            if (col != 0) {
                left = res[row][col - 1];
            }

            res[row][col] = max(up, left) + values[row * cols + col];
        }
    }
    int maxValue = res[rows - 1][cols - 1];
    for (int i = 0; i < rows; ++i) {
        delete[] res[i];
    }
    delete[] res;

    return maxValue;
}

int main() {
    int values[] = { 1,10,3,8,12,2,9,6,5,7,4,11,3,7,16,5 };
    cout << GetMaxValue(values, 4, 4) << endl;
}

我们还可以进一步优化代码,到达坐标为(i,j)的格子时能够拿到的最大礼物价值只依赖于(i-1,j)和(i,j-1)格子上的最大礼物价值,因此第i-2行及以上的计算结果没有必要缓存下来,我们可以使用一个一维数组代替上例代码中的二维数组,该一维数组的长度为棋盘列数cols,要计算坐标为(i,j)的格子的最大礼物价值f(i,j),数组中前j个数字分别为f(i,0)、f(i,1)、…、f(i,j-1),数组中从下标为j的数字开始到最后一个数字,分别为f(i-1,j)、f(i-1,j+1)、…、f(i-1,n-1)。即数组前j个数字保存当前第i行前面j个格子礼物的最大价值,而之后的数字分别保存上一行第i-1行从第j个格子开始的最大礼物价值。当计算到f(i,j)时,直接从一维数组的第j个元素的左边元素和第j个元素中选出较大一个,再和第(i,j)上的礼物价值相加即为(i,j)上的最大礼物价值:

#include <iostream>
using namespace std;

int GetMaxValue(const int* values, int rows, int cols) {
    if (values == nullptr || rows < 1 || cols < 1) {
        return 0;
    }

    int* res = new int[cols];

    for (int row = 0; row < rows; ++row) {
        for (int col = 0; col < cols; ++col) {
            int up = 0;
            if (row != 0) {
                up = res[col];    // 坐标为(i,j)的格子的上面格子的最大礼物值即在一维数组的下标为j的格子上
            }

            int left = 0;
            if (col != 0) {
                left = res[col - 1];    // 坐标为(i,j)的格子的左面格子的最大礼物值即在一维数组的下标为j-1的格子上
            }

            res[col] = max(up, left) + values[row * cols + col];
        }
    }
    int maxValue = res[cols - 1];

    delete[] res;

    return maxValue;
}

int main() {
    int values[] = { 1,10,3,8,12,2,9,6,5,7,4,11,3,7,16,5 };
    cout << GetMaxValue(values, 4, 4) << endl;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

剑指offer 学习笔记 礼物的最大价值 的相关文章

  • VM ubuntu所在的移动硬盘意外接触不良,虚拟机异常退出后无法重启

    我的VM版本为VMware Workstation 17 Pro Ubuntu版本为22 04 一次因为虚拟机所在的移动硬盘接触不良 异常退出 重启主机后启动虚拟机 先是ubuntu ubuntu高级选项等选项让我选 然后在我选择了ubun
  • linux---sed命令

    sed命令目录 一 sed命令概念 二 sed命令的格式 1 在命令行定义编辑器命令 2 在命令行使用多个编辑器命令 3 从文件中读取编辑器命令 三 更多的替换选项 1 替换标记 有4种可用的替换标记 2 替换字符 四 使用地址 在sed编
  • 07FFMPEG的AVCodec结构体分析

    07FFMPEG的AVCodec结构体分析 概述 该结构体位于libavcodec库中的codec h中 注意 非公共区域的字段我可能不会翻译 因为翻译也不知道说什么 还是保留着原文更好 其它的结构体分析同理 1 AVCodec 结构体 t
  • 银联支付(亲测成功)

    银联支付 SDK使用 测试流程 此文为银联入门 比较简单 不涉及springboot springcloud 普通web就可以 作者是eclipse 下载demo开发包 https open unionpay com upload down
  • 朴素贝叶斯解决天气问题

    朴素贝叶斯是一种基于贝叶斯定理的分类方法 该算法是有监督的学习算法 解决分类问题 在该算法中 我们假设给定目标值时 属性之间相互条件独立 即 贝叶斯定理 对于分类问题 样本x属于类别y的概率 其中 P y 是指未使用数据训练分类器之前的y的
  • 机器学习方法篇(9)------梯度提升决策树GBDT

    每周一言 生命在于运动 无论脑力还是体力 导语 前面第3 4两节介绍了决策树 由于决策树简单有效 可解释性强 因此被包装成了一些更为高效的机器学习算法 其中最为知名的就是梯度提升决策树GBDT Gradient Boosting Decis
  • 使用RoboForm自动填写表单

    日常工作中 我们也许经常要填写一些内容一模一样的表格 很是讨厌 这里使用RoboForm可以自动填充表格 大大提高我们的工作效率 一 自动填登录页面密码 比如我想登录 右击空白处 选择 RoboForm工具栏 就可以在网页下端显示该工具栏

随机推荐

  • 实训十四:FTP服务器搭建

    实训十四 FTP服务器 2017 年 6 月 6 日编写 今日公布出来 一 搭建FTP服务器 检查网络是否正常 查看 和 连通性 查看主机名称 查看是否已经自动挂载光盘 清楚到光盘挂载的目录 进入挂载安装包中 查看ftp的RPM包 并是安装
  • LeetCode——1798. 你能构造出连续值的最大数目

    一 题目 给你一个长度为 n 的整数数组 coins 它代表你拥有的 n 个硬币 第 i 个硬币的值为 coins i 如果你从这些硬币中选出一部分硬币 它们的和为 x 那么称 你可以 构造 出 x 请返回从 0 开始 包括 0 你最多能
  • ADC 模数转换实验

    生活中的模拟信号 如温度 声音 压力等 需要转换为更方便储存 处理和发射的数字形式 51 单片机无法直接操作这些模拟量 其系统内部时运算都是数字量 0 和 1 因此必须将模拟量转换成数字量 数字量 指的是用一系列 0 和 1 组成的二进制代
  • 单点登录的简单应用

    单点登录 single sign on 解决了分布式下用户登录的信息管理问题 可以自行增强安全策略 并且登录的跨域也不会再成为问题 业务流程 创建两个不同的模块 一个作为客户端 一个作为登陆服务器 都需要引入redis 对于客户端代码如下
  • [java] Map循环遍历的5种方法实现

    java Map循环遍历的5种方法实现 文章目录 一 方法一 推荐 二 方法二 推荐 三 方法三 四 方法四 五 方法五 总结 一 方法一 推荐 推荐使用此方法效率比较高 Map
  • Markdown 技能树(9):表格

    Markdown 技能树 9 表格 在 Markdown 中创建表格的语法要求如下 第一行包含表头 并用 竖线 分隔 第二行将标题与单元格分开 并且必须包含三个或更多破折号 第三行以及随后的任何行均包含单元格值 需要注意的是 不能在 Mar
  • xcode 第三方库 Incompatible block pointer types sending

    Incompatible block pointer types sending void PINMemoryCache strong NSString strong strong id to parameter of type PINCa
  • AtCoder Beginner Contest 212 D - Querying Multiset (优先队列+思维)

    链接 题意 三种操作 向队列中放入一个x 将队列中的数都 x 拿出队列中最小的数 并输出 分析 首先我们知道本题的难点在于维护每次给队列中的数 x因为队列中的数加入的顺序不一样 所以第2种对队列中的贡献有的多有的少 我说的不太清楚 谨慎理解
  • 3步排查,3步优化,探针性能损耗直降44%

    应用接探针除了安全问题 最担心的就是占用系统性能影响业务正常运转 今天分享一个实际案例告诉大家如何来降低探针的性能损耗 下表为某用户的2条核心链路在200并发压测下的性能数据对比 可以看见在接入探针后性能损耗居高不下 3步快速排查 1 对比
  • iOS内购 - 服务端票据验证及漏单引发的思考

    因业务需要实现了APP内购处理 但在过程中出现了部分不可控的因素 导致部分用户反映有充值不成并漏单的情况 仔细考虑了几个付费安全上的问题 凡是涉及到付费的问题都很敏感 任何一方出现损失都是不能接受的 所以在这里整理一些支付安全的要点分享一下
  • 从占领(工商)行业开始:国产中间件杀出血路

    导语 近日 辽宁全省工商管理系统的中间件平台花落金蝶中间件 继在广东省工商系统中获得成功后金蝶中间件在工商行业再次取得重要进展 成熟产品成熟应用 国产中间件渐成大器 在电子政务市场不断突破 国庆长假结束后的第一天 10月8日 辽宁省鞍山市工
  • DY直播运营(持续更新)

    前言 首先感谢 佳灵MM和江北帅哥 的教导 才有了作者的这篇笔记 毕业后做计算机实习工作 发现实际工作待遇和付出与理想不符之后 几经思考也受到了杭州电商的影响决心转行 机缘巧合下 在两位老师的课堂上听了半天课 收益很多 之后打算去全身心学习
  • PCI-E接口的学习

    一 pci e接口的概念 PCI E全称PCI Express peripheral component interconnect express 外部设备互连总线接口 由intel提出并推广 所连接的设备分配独享通道带宽 不共享总线带宽
  • 梯度下降法的三种解释(BGD,SGD,MBGD).

    机器学习里面 梯度下降法可以说是随处可见 虽然它不是什么高大上的机器学习算法 但是它却是用来解决机器学习算法的良药 我们经常会用到梯度下降法来对机器学习算法进行训练 在很多介绍梯度下降的书籍里 我们看到这样的几个英文单词缩写 BGD SGD
  • 互联网JAVA面试常问问题(一)

    一 为什么要创建线程池 线程是稀缺资源 使用线程池可以减少创建和销毁线程的次数 每个工作线程都可以重复使用 可以根据系统的承受能力 调整线程池中工作线程的数量 防止因为消耗过多内存导致服务器崩溃 二 创建线程池参数有哪些及其含义 publi
  • angular4点击事件监听_事件与接口

    首先来讲一下接口 接口的格式是 interface public interface 接口名 接口中有几点注意事项值得特别提醒 1 接口中不能定义变量 2 接口中的方法没有方法体 3 接口中不能实例化对象 4 类的接口可以实现多个 怎么实现
  • 小组活动学习

    0区别问题类型 问题是常规问题还是非常规问题 常规 1 理解问题需求2 理解相关概念3 搜索intenet book ask4 测试 实践 非常规1理解问题 未知 已知 条件2 拟定方案3执行方案4 回顾 警惕 需求不明朗就行动 思绪紊乱
  • C++Primer第五版习题答案(三)

    第三章 字符串 向量和数组 3 2 3 4 3 5 3 6 3 20 3 22 3 23 3 24 3 31 3 32 3 35 3 36 3 39 3 40 3 41 3 42 对于P115中int p 4 ia 为什么不是int p 3
  • Richer Convolutional Feature for Edge Detection

    Richer Convolutional Feature for Edge Detection 文章链接为Richer Convolutional Feature for Edge Detection 这篇文章通过结合所有有意义的卷积的fe
  • 剑指offer 学习笔记 礼物的最大价值

    面试题47 礼物的最大价值 在一个mxn的棋盘的每一格都放有一个礼物 每个礼物都有一定的价值 价值大于0 你从棋盘的左上角开始拿格子里的礼物 并每次向右或者向下移动一格 直到到达棋盘的右下角 给定一个棋盘和上面的礼物 请计算你最多能拿到多少