[动态规划及递归记忆搜索法]1.钢条切割问题

摘要

本系列从6道经典的动态规划题入手,去理解动态规划的基本思路和想法,以及动态规划和递归记忆搜索法存在的某些联系,对于每道题目,我们将用两种方法去实现,这里讲解第一道题目,作个开头。

前言

我们知道,大部分的动态规划题目可以利用递归加记忆搜索法去完成,这两者的程序速度方面并没有较大的区别。

动态规划(DP)和记忆化搜索(也称为递归记忆)是两种解决复杂问题的常用技术,它们都利用了子问题的解来构建原问题的解。

动态规划是一种自底向上的方法,它首先解决子问题,然后基于子问题的解来解决更大的问题。动态规划通常使用一个表格来存储子问题的解,这样在需要时就可以直接查找,而不需要重新计算。因此,动态规划通常用于最优化问题,如最短路径问题、最大子序列和问题等。

记忆化搜索是一种自顶向下的方法,它从原问题开始,然后递归地解决子问题。当一个子问题被解决时,它的解将被存储起来,以便在后续需要时使用。记忆化搜索在处理具有重叠子问题的递归问题时非常有效。

在速度上,动态规划和记忆化搜索通常具有相似的时间复杂度,因为它们都利用了子问题的解来避免重复计算。然而,具体的速度可能会根据问题的特性以及实现的细节而有所不同。例如,对于某些问题,动态规划可能需要解决所有的子问题,而记忆化搜索则只需要解决那些实际上被用到的子问题。因此,对于这些问题,记忆化搜索可能会比动态规划更快。然而,对于其他问题,动态规划可能会有更好的性能,因为它可以更有效地利用存储的子问题解。

总的来说,选择使用动态规划还是记忆化搜索通常取决于问题的特性以及个人的编程风格和经验。

题目

1.钢条切割问题

题目描述

Serling公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本支出。公司管理层希望知道最佳的切割方案。假定我们知道Serling公司出售一段长为i英寸的钢条的价格为pi(i=1,2,…,单位为美元)。钢条的长度均为整英寸。
给定一段长度为n英寸的钢条和一个价格表pi(i=1,2,…n),求切割钢条方案,使得销售收益rn最大。

关于输入

第一行:n,表示购买的长钢条的长度。
接下来一行包含 n 个数字,第 i 个数字出售长为 i 的钢条的价格,即 pi。
其中 0 < n <= 3000,0 < pi <= 10000。

关于输出

输出仅一行,为最大的销售收益值 rn。

例子输入
7
1 5 8 9 10 17 17
例子输出
18
提示信息

注意,如果长度为n英寸的钢条的价格pn足够大,最优解可能就是完全不需要切割。

解题思路

首先,我们从第一道题目先开始介绍一下动态规划的基本解题策略和方法:

动态规划(Dynamic Programming,简称 DP)是一种解决复杂问题的策略,主要用于优化问题,如求最大值、最小值或者计数问题等。下面是动态规划的基本思路和解决策略:

1. **确定状态**:在动态规划中,状态通常表示为一个或多个变量的组合,这些变量能够完全描述一个问题。例如,在背包问题中,状态可能是当前的重量和价值。

2. **确定状态转移方程**:状态转移方程是描述如何从一个状态到另一个状态的规则。在大多数情况下,这个规则是基于问题的特性和逻辑来确定的。例如,在最长公共子序列问题中,如果两个字符相等,那么最长公共子序列的长度就是前一个状态的长度加一;否则,最长公共子序列的长度就是前两个状态中较大的那个。

3. **确定边界条件**:边界条件描述了当问题降到最小规模时的解。例如,在斐波那契数列问题中,边界条件是第一项和第二项分别为1。

4. **计算并存储状态**:在动态规划中,一般会使用一个表格(一维、二维或者更高维度)来存储所有的状态。计算顺序通常是从边界条件开始,根据状态转移方程逐步计算出所有的状态。

5. **根据存储的状态得到最终结果**:在计算出所有的状态后,可以根据题目要求从存储的状态中得到最终的结果。

动态规划的关键是理解状态和状态转移方程的概念。一旦理解了这两个概念,就可以应用动态规划来解决各种各样的问题。在实际应用中,可能需要花费一些时间和思考来确定正确的状态和状态转移方程。

我们试着带着这些想法去审视本题,题目给出了两个信息:钢条的总长度和每一段特定长度的钢条的价钱。如果我们选用一个dp数组,我们先考虑一下自己需要几维的dp数组,入门阶段来说,一般我们考虑一维或者二维就可以了,这取决于我们给的状态能否完全描述一个问题(比如我上篇写的旅行商问题,由于状态过于复杂,我们采用了一种二进制压缩状态的方法作为dp数组的一个变量,用当前所在城市作为dp数组的第二个变量,以此来构建整个问题)。

对于这个钢条切割的问题,其实根据题目给的信息,又由于钢条是连续的,长度的价格也是连续的,所以一个变量即可比较好的描述我们的问题的,我们这样定义,dp[n]表示,切割n长度的钢条可以获得的最大收益。

接下来,让我们先去想想转移方程,要切割n长度的钢条,我们是不是可以选择先切割一长度下来,再切割[n-1]长度的钢条?或者说,先切割k长度的钢条,再切割[n-k]长度钢条?其中k=1,2,3.....,n。这样,为求出最大的价钱,我们可以利用以下的动态规划转移方程:

dp[n]=max{dp[n-1]+p[1],dp[n-2]+p[2],......,dp[0]+p[n]}。

再来定义一下边界条件,显然,dp[0]=0,切割0长度的钢条自然一分钱没有。

这样的转移方程合理吗?能推导出最终的答案吗?如果能,又怎么用程序去实现?

首先,为了完成这个过程,一个循环是不太够的,我们需要用两层循环,外层循环控制一个变量k,表示先切割k长度的钢条下来,因为对于每个长度的钢条我们需要比较的次数是不一样的,第二层循环用一个变量j,表示当前对j长度的钢条操作,当j为[1]时,我们只需要比较一次,就是dp[1],当j为2时,我们会比较两次,dp[2-1]+p[1] 和dp[2-2]+p[2],当j=3时,我们会比较三次,dp[3-1]+p[1] dp[3-2]+p[2],dp[3-3]+p[0],以此类推,而且由于我们是从低往高处推导的,所以,对于n=n-1时候,命题成立,我们可以推出对于n时命题也成立,而且经过我们的验证,n=1和n=2时都满足题意,故,这样的算法是可行的。

问题一dp代码展示
#include <iostream>
using namespace std;
#define INF 1e9int p[3005];
int dp[3005];int main() {int n; cin>>n;for(int i=1;i<=n;i++){cin>>p[i];}for(int i=1;i<=n;i++){dp[i]=-INF;}dp[0]=0;for(int k=1;k<=n;k++)for(int j=k;j<=n;j++){dp[j]=max(dp[j],dp[j-k]+p[k]);}cout<<dp[n]<<endl;return 0;
}
这里再附上使用记忆搜索法加递归函数的方法的代码:

定义f(n)表示切割n长度钢条能得到的最大收益

#include <iostream>
using namespace std;int p[3005];
int dp[3005];int f(int n){if(n<=0){return 0;}if(dp[n]!=-1){return dp[n];}for(int k=1;k<=n;k++){dp[n]=max(dp[n],f(n-k)+p[k]);}return dp[n];
}int main() {int n; cin>>n;for(int i=1;i<=n;i++){cin>>p[i];}for(int i=1;i<=n;i++){dp[i]=-1;}cout<<f(n)<<endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/207245.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

elasticsearch 内网下如何以离线的方式上传任意的huggingFace上的NLP模型(国内避坑指南)

es自2020年的8.x版本以来&#xff0c;就提供了机器学习的能力。我们可以使用es官方提供的工具eland&#xff0c;将hugging face上的NLP模型&#xff0c;上传到es集群中。利用es的机器学习模块&#xff0c;来运维部署管理模型。配合es的管道处理&#xff0c;来更加便捷的处理数据…

吴恩达《机器学习》12-1:优化目标

在机器学习的旅程中&#xff0c;我们已经接触了多种学习算法。在监督学习中&#xff0c;选择使用算法 A 还是算法 B 的重要性逐渐减弱&#xff0c;而更关键的是如何在应用这些算法时优化目标。这包括设计特征、选择正则化参数等因素&#xff0c;这些在不同水平的实践者之间可能…

UG NX二次开发(C#)-求曲线在某一点处的法矢和切矢

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、在UG NX中创建一个曲线3、直接放代码4、测试案例1、前言 最近确实有点忙了,好久没更新博客了。今天恰好有时间,就更新下,还请家人们见谅。 今天我们讲一下如何获取一条曲线上某一条曲…

注意力机制的快速学习

注意力机制的快速学习 注意力机制 将焦点聚焦在比较重要的事物上 我&#xff08;查询对象Q&#xff09;&#xff0c;这张图&#xff08;被查询对象V&#xff09; 我看一张图&#xff0c;第一眼&#xff0c;就会判断那些东西对我而言比较重要&#xff0c;那些对于我不重要&…

Pytorch从零开始实战12

Pytorch从零开始实战——DenseNet算法实战 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——DenseNet算法实战环境准备数据集模型选择开始训练可视化总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.…

Elasticsearch、Logstash、Kibana(ELK)环境搭建

下面是 Elasticsearch、Logstash、Kibana&#xff08;ELK&#xff09;环境搭建的具体操作步骤&#xff1a; 安装 Java ELK 是基于 Java 编写的&#xff0c;因此需要先安装 Java。建议安装 Java 8 或以上版本。 下载并安装 Elasticsearch Elasticsearch 是一个基于 Lucene 的…

DevEco Studio 运行项目有时会自动出现.js和.map文件

运行的时候报错了&#xff0c;发现多了.js和.map&#xff0c;而且还不是一个&#xff0c;很多个。 通过查询&#xff0c;好像是之前已知问题了&#xff0c;给的建议是手动删除(一个一个删)&#xff0c;而且有的评论还说&#xff0c;一周出现了3次&#xff0c;太可怕了。 搜的过…

【网络编程】-- 02 端口、通信协议

网络编程 3 端口 端口表示计算机上的一个程序的进程 不同的进程有不同的端口号&#xff01;用来区分不同的软件进程 被规定总共0~65535 TCP,UDP&#xff1a;65535 * 2 在同一协议下&#xff0c;端口号不可以冲突占用 端口分类&#xff1a; 公有端口&#xff1a;0~1023 HT…

【android开发-23】android中WebView的用法详解

1&#xff0c;WabView的用法 在Android中&#xff0c;WebView是一个非常重要的组件&#xff0c;它允许我们在Android应用中嵌入网页&#xff0c;展示HTML内容。WebView是Android SDK中提供的标准组件&#xff0c;使用它我们可以很方便地将web页面直接嵌入到Android应用中。Web…

亚信安慧AntDB数据库中级培训ACP上线,中国移动总部首批客户认证通过

近日&#xff0c;亚信安慧AntDB数据库ACP&#xff08;AntDB Certified Professional&#xff09;中级培训课程于官网上线。在中国移动总部客户运维团队、现场项目部伙伴和AntDB数据库成员的协同组织下&#xff0c;首批中级认证学员顺利完成相关课程的培训&#xff0c;并获得Ant…

自然语言处理22-基于本地知识库的快速问答系统,利用大模型的中文训练集为知识库

大家好,我是微学AI,今天给大家介绍一下自然语言处理22-基于本地知识库的快速问答系统,利用大模型的中文训练集为知识库。我们的快速问答系统是基于本地知识库和大模型的最新技术,它利用了经过训练的中文大模型,该模型使用了包括alpaca_gpt4_data的开源数据集。 一、本地…

C //例10.3 从键盘读入若干个字符串,对它们按字母大小的顺序排序,然后把排好序的字符串送到磁盘文件中保存。

C程序设计 &#xff08;第四版&#xff09; 谭浩强 例10.3 例10.3 从键盘读入若干个字符串&#xff0c;对它们按字母大小的顺序排序&#xff0c;然后把排好序的字符串送到磁盘文件中保存。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差异。 代码块 方法…

2023_Spark_实验二十五:SparkStreaming读取Kafka数据源:使用Direct方式

SparkStreaming读取Kafka数据源&#xff1a;使用Direct方式 一、前提工作 安装了zookeeper 安装了Kafka 实验环境&#xff1a;kafka zookeeper spark 实验流程 二、实验内容 实验要求&#xff1a;实现的从kafka读取实现wordcount程序 启动zookeeper zk.sh start# zk.sh…

生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

如果x加上x的各个数字之和得到y&#xff0c;就说x是y的生成元。 给出n&#xff08;1≤n≤100000&#xff09;&#xff0c;求最小生成元。 无解输出0。 例如&#xff0c;n216&#xff0c;121&#xff0c;2005时的解分别为198&#xff0c;0&#xff0c;1979。 我的思路很简单&am…

element-UI中el-scrollbar的使用

在elment-ui中有这么一个滚动条&#xff0c;当鼠标over到内容部分才会显示&#xff0c;移开鼠标之后滚动条就会隐藏起来&#xff0c;相较于原生的滚动条比较美观。 <el-scrollbar> //将滚动条的内部的内容放在里面即可 </el-scrollbar> 在使用过程中&#xff…

SNMP陷阱监控工具

SNMP&#xff08;简单网络管理协议&#xff09;是网络管理的一个重要方面&#xff0c;其中网络设备&#xff08;包括路由器、交换机和服务器&#xff09;在满足预定义条件时将SNMP陷阱作为异步通知发送到中央管理系统。简而言之&#xff0c;每当发生关键服务器不可用或硬件高温…

microblaze仿真

verdivcs (1) vlogan/vcs增加编译选项 -debug_accessall -kdb -lca (2) 在 simulation 选项中加入下面三个选项 -guiverdi UVM_VERDI_TRACE"UVM_AWARERALHIERCOMPWAVE" UVM_TR_RECORD 这里 -guiverdi是启动verdi 和vcs联合仿真。UVM_VERDI_TRACE 这里是记录 U…

第四十二篇,MATLAB on Linux

最近在Ubuntu上安装了一把MATLAB&#xff0c;以下操作亲测有效。 一、版本 Linux&#xff1a;Ubuntu 18.04 MATLAB&#xff1a;R2021a Linux版&#xff0c;910 MATLAB下载链接&#xff1a;提取码MUYU&#xff0c;感谢大佬无私奉献&#xff01; 二、安装 详细的安装步骤不…

linux高级篇基础理论七(Tomcat)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️不能因为人生的道路坎坷,就使自己的身躯变得弯曲;不能因为生活的历程漫长,就使求索的 脚步迟缓。 ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xff1a;云计算技…

算法题,文本左右对齐

/*** 给定一个单词数组 words 和一个长度 maxWidth &#xff0c;重新排版单词&#xff0c;使其成为每行恰好有 maxWidth 个字符&#xff0c;且左右两端对齐的文本。** 你应该使用 “贪心算法” 来放置给定的单词&#xff1b;也就是说&#xff0c;尽可能多地往每行中放置单词。必…