继续讲故事~~

  我们的主人公现在已经告别了生于斯,长于斯的故乡,来到了全国最大的城市S市。这座S市,位于国家的东南部,是全国的经济中心,工商业极为发达,是这个国家的人民所向往的城市。这个到处都留着奶与蜜的城市,让丁丁充满了好奇感和新鲜感,他多想好好触摸这个城市的脉搏啊!

  这不,他此刻正走在城市的某高新园区,不远处传来钢条切割的声音。他好奇地走上前去,看着工人们正在熟练地切割钢条,并打包完成包装。此时,一位工人看到了丁丁,一看,竟是自己的同乡。他热情地上去打了招呼,并询问了乡下的情况,他俩约了中午一起吃饭。

  午饭时,老乡热情地请丁丁在园区最好的饭店吃饭,他俩聊得也很开心。突然,老乡想到了丁丁学过计算机方面的理论,于是他准备把自己最近遇到的问题告诉丁丁,看看他能不能解决。

钢条切割问题: 给定一段长度为n英寸的钢条和一个价格表\(p_i(i=1,2,...,n)\),求切割钢条方案,使得销售收益\(R_n\)最大。注意,如果长度为n英寸的钢条的价格\(p_n\)足够大,最优解可能就是完全不需要切割。

已知钢条价格表如下:



  听到老乡正在为整个问题发愁,丁丁内心也想着尝试解决这个问题。毫无疑问,这个问题也是可以用动态规划法解决的,于是,他拿出稿纸推演起来:

将钢条从左边切割下长度为i的一段,只对右边剩下的长度为n-i的一段继续进行切割(递归求解),对左边的一段则不再进行切割。这样,不做任何切割的方案可以描述为:第一段长度为n,收益为pn,剩余部分长度为0,对应的收益为\(R_0\)=0。于是,我们就得到该问题的求解公式:

\[R_n=\min\limits_{1\leq i \leq n}(p_n+R_n-1)
\]

采用自底向上法(bottom-up method)来求解该问题,需要用一个列表来记录收益\(r_n\),一个列表来记录切割方案,其Python代码如下:

import time
# 使用动态规划法(dynamic programming)解决钢条切割问题 # 钢条长度与对应的收益
length = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
profit = (1, 5, 8, 9, 10, 17, 17, 20, 24, 30) # 动态归纳法,自底向上的CUT-ROD过程,加入备忘机制
# 运行时间: 多项式
# 参数:profit: 收益列表, n: 钢条总长度
# 返回参数: q: 最大收益
def bottom_up_cut_rod(profit, n):
r = [0] # 收益列表
s = [0]*(n+1) # 切割方案列表 for j in range(1, n+1):
q = float('-inf')
for i in range(1, j+1):
if max(q, profit[length.index(i)]+r[j-i]) == profit[length.index(i)]+r[j-i]:
s[j] = i
q = max(q, profit[length.index(i)]+r[j-i]) r.append(q)
return r[n], s[n] # method of how to cut the rod
def rod_cut_method(profit, n):
how = []
while n != 0:
t,s = bottom_up_cut_rod(profit, n)
how.append(s)
n -= s return how for i in range(1, 11):
t1 = time.time()
money,s = bottom_up_cut_rod(profit, i)
how = rod_cut_method(profit, i)
t2 = time.time()
print('profit of %d is %d. Cost time is %ss.'%(i, money, t2-t1))
print('Cut rod method:%s\n'%how)

输出结果:

profit of 1 is 1. Cost time is 0.0s.
Cut rod method:[1] profit of 2 is 5. Cost time is 0.0s.
Cut rod method:[2] profit of 3 is 8. Cost time is 0.0s.
Cut rod method:[3] profit of 4 is 10. Cost time is 0.0s.
Cut rod method:[2, 2] profit of 5 is 13. Cost time is 0.0s.
Cut rod method:[3, 2] profit of 6 is 17. Cost time is 0.0s.
Cut rod method:[6] profit of 7 is 18. Cost time is 0.0s.
Cut rod method:[6, 1] profit of 8 is 22. Cost time is 0.0005009174346923828s.
Cut rod method:[6, 2] profit of 9 is 25. Cost time is 0.0s.
Cut rod method:[6, 3] profit of 10 is 30. Cost time is 0.0s.
Cut rod method:[10]

不一会儿他就搞定了这个问题,他将不同长度的钢条所能获得最大收益和对应的切割方案告诉了老乡。老乡听后大喜,他为丁丁解决了这个困扰它们公司长久的问题而感到由衷高兴,有了以上的结果,那么,钢条的长度再长也不是问题了。

  午饭后,老乡将刚才吃饭时丁丁的解决方法告诉了老板,老板也是喜出望外,他决定高薪聘请这个年轻人。而我们的丁丁,他早已离开高新区,向着下一个目的地出发了~~

注意:本人现已开通两个微信公众号: 用Python做数学(微信号为:python_math)以及轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

动态规划法(五)钢条切割问题(rod cutting problem)的更多相关文章

  1. (5千字)由浅入深讲解动态规划(JS版)-钢条切割,最大公共子序列,最短编辑距离

    斐波拉契数列 首先我们来看看斐波拉契数列,这是一个大家都很熟悉的数列: // f = [1, 1, 2, 3, 5, 8] f(1) = 1; f(2) = 1; f(n) = f(n-1) + f( ...

  2. 算法导论-钢条切割 C# 递归实现

    下班前看到有位兄弟写 钢条切割问题,尝试实现C#版, 还没有实现最优版,分享一下. int[] parr; private void button1_Click(object sender, Even ...

  3. Java SE之正则表达式五:切割

    /** * * @author Zen Johnny * @date 2018年4月29日 下午3:53:55 * */ package demo.regex; /* 正则表达式:切割 */ publ ...

  4. rod cutting

    for a rod of length i the price of it si pi,to cut the rod to earn more money package dynamic_progra ...

  5. [2019HDU多校第五场][HDU 6626][C. geometric problem]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6626 题目大意:给出平面上六个点\(A,B,M,N,X,Y\)以及两条直线\(L1,L2\),要求在四 ...

  6. [Java 8] (9) Lambda表达式对递归的优化(下) - 使用备忘录模式(Memoization Pattern) .

    使用备忘录模式(Memoization Pattern)提高性能 这个模式说白了,就是将需要进行大量计算的结果缓存起来,然后在下次需要的时候直接取得就好了.因此,底层只需要使用一个Map就够了. 但是 ...

  7. 10003 Cutting Sticks(区间dp)

      Cutting Sticks  You have to cut a wood stick into pieces. The most affordable company, The Analog ...

  8. 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)

    Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...

  9. UVA 10003 Cutting Sticks(区间dp)

    Description    Cutting Sticks  You have to cut a wood stick into pieces. The most affordable company ...

随机推荐

  1. jxl操作excel写入数据不覆盖原有数据示例

    public void readTO() {        Workbook wb = null;        WritableWorkbook wwb = null;        try {   ...

  2. docker-compose安装redis-sentinel集群(1主+2副+2哨兵)

    前提:本试验环境已经提前安装了docker和docker-compose 说明:本次部署是单机伪集群,想要部署真正的集群,需要将秒个主件拆分到各个机器上去部署,只修改ip地址 1.下载redis的相关 ...

  3. 利用ONENET平台控制MPC

    可以用于广告机或者灾害预警,实时广播等行业 这个分控制端和服务端 控制端采用winform编写,服务端采用控制台程序编写 优点在于服务端不用有公网ip,比传统方案方便的多. 也不用租用费用高额的云服务 ...

  4. 《mysql必知必会》学习_第14章_20180806_欢

    第14章:使用子查询. 子查询是镶嵌在其他查询里面,相当其他的select查询的条件来. P91 select order_num from where prod_id='tnt2';   #检索条件 ...

  5. Struts2下载及简介

    Struts2下载及简介 一.Struts2下载: 进入网址:http://struts.apache.org/download.cgi#struts23163 可以下载最新的Struts2. 1.F ...

  6. pyinstaller打包程序 带图片

    首选说一下,这种打包方式只能在本电脑上使用运行正常 准备:.py文件:你的程序 gif文件:你要用的图片 第一步: 在上面文件所在目录打开cmd 输入 pyi-makespec FP.py 会生成一个 ...

  7. Java学习笔记28(集合框架二:Iterator迭代器)

    Iterator接口,翻译成中文是迭代器 迭代器的概念通俗解释: java中有很多的集合,内部有各种存储方法,取出的方式也各不相同,是否可以有一种通用的方式来获取呢? 这种方式类似for循环遍历, 通 ...

  8. Error: [ng:areq] Argument ‘AppCtrl’ is not a function, got undefined

    今天把用ionic做一个案例,和ionic示例项目差不多,只是用requirejs分离了controller,但是一直报错 Error: [ng:areq] Argument ‘AppCtrl’ is ...

  9. 机器学习基石笔记:13 Hazard of Overfitting

    泛化能力差和过拟合: 引起过拟合的原因: 1)过度VC维(模型复杂度高)------确定性噪声: 2)随机噪声: 3)有限的样本数量N. 具体实验来看模型复杂度Qf/确定性噪声.随机噪声sigma2. ...

  10. Spring Boot Tomcat配置详解

    参数配置容器 server.xx开头的是所有servlet容器通用的配置,server.tomcat.xx开头的是tomcat特有的参数,其它类似. 所有参数绑定配置类:org.springframe ...