切割钢条最大利润问题

(超简单、超易懂、超详细)算法精讲(三十六): 切割钢条算法 切割钢条算法是一个经典的动态规划问题。给定一根长度为n的钢条和一个价格表,其中给出了不同长度的钢条对应的价格,目标是找到切割方案,使得切割后的钢条总价格最大。假设价格表为p[i] (1 ≤ i ≤ n),则切割钢条的最大收益可以通过递归地解决子问题来求解。我们假定将钢条切割成长度为i和n-i两段,则切割方案的最大收益为p[i] + max(revenue(n-i)),其中revenue(k)表示长度为k的钢条的最大收益。具体的切割钢条算法可以使用自顶向下或自底向上的方法来实现。 阅读详情

问题

公司有购买长度为n(我们假设n不超过表格所列的最长长度,即n<=10)的钢条,将其切割成长度为i的钢条出售,长度为i的钢条的出售价格为p[i]。钢条的长度为整数,求切割方案,使得销售利益最大。

长度价格
11
25
38
49
510
617
717
820
924
1030

输入:

int[] p  //长度为i的钢条价格为p[i]
int n //总长度n<=p.length

输出:

  int q//最大利润

解决方法1——朴素递归法

设长度为n的钢条,收益最大的情况要么是直接出售,不进行切割,要么是进行切割,在切割方案中选择一个最大的,所以最大利润为:

r=max{p[n],r1+r(n-1),r2+r(n-2)...r(n-1)+r1}

我们可以计算出所有切割的方法所获得利润,然后取最大值。
普通的递归方法解决:

/**
	 * 求长度为n的钢条最大价值 朴素递归方法
	 * r表示利润最大值
	 * @param p 钢条价格数组
	 * @param n 钢条长度
	 * @return
	 */
public int cut_Rod(int[] p, int n) {
		if (n == 0)// 长度为0,价值为0
			return 0;
		int r = -99999;//设置为最小值
		for (int i = 1; i <= n; i++)
			r = max(q, p[i] + cut_Rod(r, n - i));
		return r;
	}
	public int max(int q, int i) {
		// TODO Auto-generated method stub
		return q > i ? q : i;
	}

解决方法2——动态规划

可以看到,朴素递归方法反复求解相同的子问题,因此效率低下,动态规划方法将这些已经计算过的值保存下来,再次遇到相同的问题只需要查找相同问题的解,付出额外的空间来换取时间效率。
动态规划方法:多了一个数组r[i]用于存储长度为i的钢条的最大利润,求r[i]的过程还是使用的普通递归。

/**
	 * 求长度为n的钢条最大价值动态规划
	 * r表示利润最大值
	 * @param p 钢条价格数组
	 * @param n 钢条长度
	 * @return
	 */
	public int cut_Rod_Dynamic(int[] p, int n) {
		// new an array and initial to -9999
		int[] r = new int[n + 1];
		for (int i = 0; i < n + 1; i++)
			r[i] = -9999;
		return memoize_cut_rod_aux(p, n, r);
	}

	public int memoize_cut_rod_aux(int[] p, int n, int[] r) {
		int q;
		// 检查数组中是否有保存的值,有的话直接返回
		if (r[n] >= 0)
			return r[n];
		// 递归计算q,长度为0返回0
		if (n == 0)
			q = 0;
		else {
			q = -9999;
			for (int i = 1; i <= n; i++) {
				q = max(q, p[i] + memoize_cut_rod_aux(p, n - i, r));
			}
			r[n] = q;
		}
		return q;
	}

还可以改进这个算法,不必进行递归调用,对于已经计算过的结果我们应该加以利用:

/**
	 * 自底向上的计算长度为i的钢条的最大价格
	 * @param p
	 * @param n
	 * @return
	 */
	public int bottom_up_cut(int []p,int n)
	{
		// new an array and initial to -9999
		int[] r = new int[n + 1];
		for (int i = 0; i < n + 1; i++)
			r[i] = -9999;
		r[0]=0;//长度为0的价格为0
		for(int i =1;i<=n;i++)
		{
			int q=-9999;
			for(int j = 1;j<=i;j++)
			{
				q= max(q,p[j]+r[i-j]);//这个我们利用了r[i-j]来获取长度为i-j的钢条的最大利润
			}
			r[i]=q;
		}
		return r[n];
	}

3.扩展

3.1如果给定的钢条长度超过了表格中的最大长度,该怎么计算最大利润呢?

很简单,同样采用递归的方法,如果钢条长度大于了最大的长度,将之截成两段分别求最大利润,相加即可。所以如果对n大小没有限制的话,只需要在程序开始加一个判断就行了。

// 如果长度超过了数组的长度,分开计算,分治
		if (n > p.length - 1)
			return cut_Rod_Dynamic(p, p.length - 1) + cut_Rod_Dynamic(p, n - (p.length - 1));

但是这个中方法还是存在弊端,也是重复计算了相同的问题,有待改进。

3.2 如果要求切割方案呢?

在自底向上的切割方法中,我们可以记录当前最优解的第一段钢条的长度,声明一个额外的数组int s[],s[i]存放长度为i的钢条最优解的切割方案的第一条钢条的长度,最后打印出来即可。
总体代码如下:

public int cut_Rod_Dynamic(int[] p, int n) {
		int[] s = new int[n + 1];
		// 如果长度超过了数组的长度,分开计算,分治
		if (n > p.length - 1)
			return cut_Rod_Dynamic(p, p.length - 1) + cut_Rod_Dynamic(p, n - (p.length - 1));
		// new an array and initial to -9999
		int[] r = new int[n + 1];
		for (int i = 0; i < n + 1; i++)
			r[i] = -9999;
		int res = bottom_up_cut(p, n,s);
		//打印切割方案
		while(n>0){
			System.out.println(s[n]);
			n-=s[n];
		}
		return res;
	}
/**
	 * 自底向上的计算长度为i的钢条的最大价格,并记录切割方案
	 * @param p
	 * @param n
	 * @return
	 */
	public int bottom_up_cut(int []p,int n,int []s)
	{
		// new an array and initial to -9999
	
		int[] r = new int[n + 1];
		for (int i = 0; i < n + 1; i++) {
			r[i] = -9999;
			s[i] = -9999;
		}
		r[0]=0;//长度为0的价格为0
		for(int i =1;i<=n;i++)
		{
			int q=-9999;
			for(int j = 1;j<=i;j++)
			{
				if(q<p[j]+r[i-j]) {
					q= max(q,p[j]+r[i-j]);
					s[i]=j;//在这里记录了最优解的切割方案
				}
			}
			r[i]=q;
		}
		return r[n];
	}

钢条切割问题:动态规划算法的典型应用 在工业生产和物流管理中,钢条切割问题是一个常见的优化问题。企业在购买长钢条并将其切割为短钢条出售时,往往面临着如何切割以最大化利润的问题。这个问题不仅关系到企业的成本控制和利润最大化,也涉及到资源的有效利用和生产效率的提升。本文将介绍钢条切割问题的数学模型,以及如何运用动态规划算法来寻找最优的切割方案。 阅读详情

相关推荐

钢条切割-【算法导论-动态规划】

对以上的价格表样例,进行模拟切割: r1 = 1,切割方案1 = 1(无切割) r2 = 5,切割方案2 = 2(无切割) r3 = 8, 切割方案3 = 3(无切割) r4 = 10, 切割方案4 = 2 + 2 r5 = 13, 切割方案5 = 2 + 3 r6 = 17, 切割方案6 = 6(无切割) r7 = 18, 切割方案7 = 1 + 6或7 = 2 + 2 + 3 r8 = 22, 切割方案8 = 2 + 6 r9 = 25, 切割方案9 = 3 + 6 r10 = 30,切割方案10 = 10(无切割) 可能现在大家对这种切割比较不耐烦,或者是有的数并不是那么好,怎么办? 这时有个很好的思想,就是动态规划,之前模拟切割尽管结果出来的很简单,但是过程却依然很复杂; 比如r7,它有很多切割方案,1-6,2-5,3-4,2-2-3,1-1-5等等,这些过程如何自己来模拟的话实在是太费时间,但是我们想在切割7的时候前面都已经完成了,我们可以在前面的基础上进行切割,这时只要考虑1-6,2-5,3-4即可,比如现在的1-6就包括了之前的1-1-5,1-2-4等的切割方案;

C语言(CED)钢条最优切割收益

一、题目大意 一家公司购买长钢条,将其切割成短钢条出售,切割本身没有成本,长度为i的短钢条的价格为Pi。那给定一段长度为n的钢条和一个价格表Pi,求钢条的切割方案使得收益Rn最大。提示:将钢条切割为长度为i和n - i两段,接着求解这两段的最优切割收益Ri和Rn - i 二、大致思路 本题用到的知识点就是动态规划,以下简称DP,我在解决此题的时候,思路在刚开...

Cat 1463

从零搭建ROS1导航小车(一):松灵SCOUT Mini底盘通讯配置与ROS包编译避坑指南

本文详细介绍了从零开始搭建ROS1导航小车的初始步骤,重点讲解松灵SCOUT Mini底盘的通讯配置与ROS包编译避坑指南。内容包括硬件连接、CAN通讯配置、ROS工作空间构建及编译优化等实用技巧,帮助开发者快速实现自主导航小车的通讯功能。

weixin_27014595的博客 188

算法导论——钢条切割问题(C语言)

《算法导论》在对动态规划讲解时,第一个问题就是钢条切割的问题。 在书中,对这个问题提供了3种思路 利用普通的递归来解,时间复杂度为O(2^n) 对普通的递归进行优化,使其带有记忆功能,减少运行时间。即自顶向下的动态规划 运用数组,自底向上的动态规划 现在依次讲解这三个思路,并且用代码实现它们! 首先先看题 现在给你一根钢条,你可以把它切成几个小部分(也可以不用切割),要找到一种方法,使得这根钢条可以卖出最多的价钱。 如:长度为4的钢条有三种卖法 不切割直接买,可以买价格9 切割为1,3再买,同样是价

brench11的博客 4712

从Maya到Unity:3D模型导入全流程避坑指南(含FBX导出设置)

本文详细解析了从Maya导出3D模型至Unity的全流程,重点剖析了FBX格式作为跨软件协作“中间人”的优劣与核心设置。指南涵盖了Maya端模型清理、FBX导出关键配置(如嵌入媒体、轴转换),以及Unity端的模型、材质、动画导入优化与常见问题(如材质丢失、UV法线错误、骨骼动画错乱)的实战解决方案,旨在帮助3D美术师与技术美术建立稳定、高效的工作流。

lg888的博客 791

Pytorch实现softmax多分类

PyTorch实现softmax多分类

天涯雨的博客 1387

动态规划:求解任意长度钢条切割效益最大化问题

钢条切割问题是动态规划中的一个经典问题。这个问题的目标是将一根长度为n的钢条切割成若干小段,使得这些小段的总收益最大。这里的收益指的是每一小段钢条的价格之和。某公司出售一段长度为 i (单位: m) 的钢条, 对应的价格为 p_i, 钢条 长度为整数, 下面表格给出对应价格表。没有列出10以上的钢条价格,可以认为由于运输或设备问题,公司不能力售出10米以上的钢条。这个问题可以使用动态规划来解决。

hongshanqu的博客 525

Vivado时序违约小结

目录1. setup time违约1.1 逻辑级数太高1.2 Fanout太大2. hold time 违约2.1 异步信号处理导致hold time违约 1. setup time违约 建立时间是工程设计中最常遇到的问题了。一般说来,导致建立时间违例主要有两个原因:逻辑级数太大或者扇出太大,当然也可以尝试通过降频来解决建立时间违约。 1.1 逻辑级数太高 Levels指的是逻辑级数logic level,一个logic level的延迟对应的是一个LUT和一个Net的延迟,对于不同的器件,不同频率的设计能

mu_guang_的博客 7155

股票问题(贪心算法)----最大利润

问题描述 假设你有一个数组,其中第i 个元素是第i天给定股票的价格。设计算法以找到最大利润。你可以根据需要完成尽可能多的交易(即,多次买入并卖出一股股票)。 注意:您不能同时进行多笔交易(即,您必须在再次购买之前卖出股票) 贪心算法 什么是贪心算法? 顾名思义,贪心算法总是做出在当前看来是最好的选择。也就是说,贪心算法并不从整体最优上加以考虑,所做的选择只是在某种意义上的局部最优解。当然,我们希望贪心算法得到的最终结果也是整体最优的。 贪心算法的性质 所求问题的整体最优解可以通过一系列局部最优解的选择,即贪

巩固的微笑的博客 4564

TL3562/3568内核驱动移植实战:解决无锡沐创N500L-AM4网口异常问题

本文详细介绍了在TL3562/3568平台上移植无锡沐创N500L-AM4网卡驱动的实战经验,重点解决了第四个网口通讯异常问题。通过升级驱动版本至rnpgbe-0.2.3,生成关键头文件并正确配置内核,最终实现四个网口稳定工作。文章还提供了性能优化建议和避坑指南,为类似硬件驱动移植项目提供参考。

weixin_28273593的博客 180

【ComfyUI】Wan 2.2 14B 首尾帧转视频 平滑过渡

本文介绍了基于 Wan2.2 ComfyUI 的视频生成工作流,通过预训练模型、提示词与参考图像的结合,实现高质量视频合成。工作流采用高低噪声模型与 LoRA 模块优化风格与细节,确保画面过渡平滑稳定。核心流程包括模型加载、图像输入、提示词编码、潜空间采样、解码与视频合成,最终生成动态转场视频。节点设计涵盖 CLIPTextEncode、KSamplerAdvanced 等关键模块,协同完成从文本到视频的全链路生成。正向提示词作为核心驱动力,直接影响视频的动作、镜头与画面变化。

Mr数据杨 1701

【算法-动态规划】钢条切割问题:解锁利润最大化的秘密

动态规划是一种解决多阶段决策过程最优化问题的方法,它将大问题分解为子问题,通过存储子问题的解来避免重复计算,从而达到高效求解的目的。对于钢条切割问题,动态规划的关键在于识别并利用重叠子问题的性质,减少冗余计算。

master_chenchen的博客 1055

【ComfyUI】Wan2.2 + IndexTTS 图像数字人或动物口播视频生成

本文介绍了一个基于ComfyUI的数字人口播视频生成工作流,整合了IndexTTS和图像处理技术。该系统通过多模型协同工作,实现从形象图、文本和音频输入到自动生成口播视频的全流程。核心包含WanVideo系列模型,通过CLIP Vision、T5文本编码器和Wav2Vec语音模型分别处理视觉特征、语义理解和口型同步。工作流涵盖素材加载、特征提取、音频处理和视频生成等节点,支持人物、动物等多种主体的口播内容创作。该方案自动化程度高,适用于知识讲解、剧情旁白等多种场景,能帮助创作者高效产出高质量口播视频。

Mr数据杨 2052

动态规划之钢条分割

长度i     1      2     3  4  5  6     7  8  9  10 价格Pi   1     5     8  9  10  17   17  20  24  30 上图分别是长度为i的钢条的价格;那么现在一根长度为n的钢条,求如何切割,使得利润最大? 《算法导论》205页。 如果只求最大利润的值,不需要知道分割过程,有以下两种方法:

Sunshine的专栏 2354

dolphinscheduler集群服务一键安装启动实现流程剖析

通过以上分析我们基本梳理清楚了整个dolphinscheduler项目的一键安装启动逻辑, 我们现在在通过一张图正好理一下整个实现流程。关于一键停止集群服务及一件查询集群各个角色服务实例运行状态的实现也都在stop-all.sh/status-all.sh及dolphinscheduler-daemon.sh这三个脚本中, 有兴趣自行研究。写这篇文章的核心目的不仅在于给大家分享如何优秀的开源项目的一键安装部署的实现过程。

最爱嫣夜来 1207

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C++实现——动态规划法(切割钢条问题)

假定公司出售一段长度为i英寸的钢条的利润为Pi,那么现有一根N英寸的钢条该如何切割才能利润最大,最大为多少。

qq_39542725的博客 888

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

动态规划之切割钢条

一公司购买长钢条,将其切为短钢条出售,假设切割没有成本,公司希望知道最佳的切割方案!假设我们知道一段长度为i的钢条的价格为pi(i = 1,2,3...),钢条长度均为整英寸,下面给出一个价格表

qeesung的专栏 4277

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

切钢条问题

[C++] 切钢条问题(动态规划)

a1651950431的博客 383

C语言——钢条切割——贪心算法

钢条切割 这道题只是我刚开始学习线性规划的自己的根据大致做法自己写的代码。作为笔记记录一下,未必是简便的程序。 //贪心算法-----钢条切割 #include<stdio.h> typedef struct pole{ float lenght; float price; float per; }Pole; int main(){ ...

weixin_44040023的博客 2083

完成最优切割问题的求解

一、问题分析 1.1 问题描述 一家公司购买长钢条,将其切割成短钢条出售,假设切割本身没有成本,长度为i的短钢条的价格为Pi。那给定一段长度为n的钢条和一个价格表Pi,求钢条的切割方案使得收益Rn最大。例如某公司以单价26元买到了一批长度为10的钢条,目前各长度钢条的市场价如下表所示: 长度i 1 2 3 4 5 6 7

m0_53737802的博客 1513

钢条切割问题(Java)——Top-down DP演算法

Rod Cutting题目: 注意: 本题采用txt文件读入,屏幕输出; 如果需要屏幕读入屏幕输出,可以留言或者自己改代码~ Top-down DP演算法: 从钢条的左边切割下一段长度为i的短钢条,然后右边为长度即为n-i的短钢条,进一步对右边继续递归求解,直到右边的长度为0,则返回零。 ——所需时间T=O( n^2) import java.io.BufferedReader; imp...

Wangzx的博客 1040

算法:动态规划(1.钢条切割)

Dynamic programming 动态规划,与分治法相似,都是通过组合字问题的解来求解原问题,但动态规划是应用于子问题重叠的场景,每个子问题都只求一遍,将解存入表格中,避免不必要的重复工作。 问题:购买长钢条,将其切割为短钢条出售,切割 ...

齐天的博客 1838

钢条分割 动态规划java_【动态规划】初识,钢条切割问题

正文之前其实动态规划老早之前就看过, 但是可惜的是印象不深,到今天彻底忘得差不多了,这两天看《算法导论》终于让我啃下了二叉搜索树和红黑树两个家伙,虽然还未曾熟练于胸,但是基本能用了。。。现在看到了动态规划,这就不得不来搞一搞了。。以一个最简单的钢条切割的示例来详解下我的收获正文首先发代码,这个是自底向上的版本,其他的版本不做多的解释,这个最好用最直观。#include#includeusing...

weixin_30269407的博客 269

动态规划--切钢筋问题

钢条切割问题: 某公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本支出。公司管理层希望知道最佳的切割方案。假设我们知道该公司出售一段长度为i英寸的钢条的价格为Pi(i=1,2,3,....)钢条的长度均为整数。下面给出一个价格表的样例 长度i 1 2 3 4 5 6 7 8 9 10 价格Pi 1 5 8 9 10 17 17 20 24 30 ...

码海淹没的小强的博客 1085

每天一道算法题-动态规划求钢筋分割

Dynamic programming 动态规划,与分治法相似,都是通过组合子问题的解来求解原问题,但动态规划是应用于子问题重叠的场景,每个子问题都只求一遍,将解存入表格中,避免不必要的重复工作。 问题:购买长钢条,将其切割为短钢条出售,不同长度的钢条对应不同的价格,希望得到最佳的切割方案使利润最大化。 长度 i 1 2 3 4 5 6 7 8 9 10 价格 p 1 5 8 9 10 17 17

javazht的博客 678

动态规划

#include "stdafx.h" #include <iostream> #include <vector> using namespace std; vector<int> MaxEarn(vector<int>p, int length, vector<int>s) { vector<int> r(length+1, 0);//初始化收益为0 for (int j = 1;

yqtao的博客 348
上一篇: Java数组声明及初始化
下一篇: Linux操作系统分析与设计——跟踪分析Linux5.0内核处理系统调用的过程
There Is No Code
博客等级 码龄10年 254粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

There Is No Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值