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

本贴最后更新于 2578 天前,其中的信息可能已经时移世改

    最优子结构和子问题重复定义可以参考算法导论。

钢条切割

    问题描述:Seriling公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本。公司管理层希望知道最佳切割方案。假定我们知道公司出售一段长度为i 英寸的钢条的价格为pi(i=1,2,3,...,n,单位为美元)。钢条的长度均为整英寸。     

长度i

1

2

3

4

5

6

7

8

9

10

pi

1

5

8

9

10

17

17

20

24

30

 

数学表达式:

对于r(n)(n>=1),总可以用更短的钢条的最优收益切割来描述它: 

                                                        r(n)=max(p(n),r(1)+r(n−1),r(2)+r(n−2)....)                           (1)
p(n)表示不切割,其他n-1个参数对应另外n-1中方案:对每个i=1,2,...n−1,首先将钢条切割为长度为i和n−i的两段,在分别求解这两段的最优切割收益。由于无法预知哪种方案获益最大,因此需要考察每一种方案。 公式(1)化简为
                                                        r(n)=max(p(i)+r(n-i))         ,1<=i<=n                                    (2)                 

实现过程中,主要应用公(2)来计算。

这里直接给出实现的方案:

import java.util.Scanner;

/**
 * Created by Rudy Steiner on 2017/3/28.
 * 算法导论 动态规划-钢条切割问题
 */
public class SteelCutting {
/* 自顶向下,朴素递归切割
* @param p: 收益数组
* @param n: 待切割钢条长度
* */
public static int tDRecursiveCut(int[] p,int n){
    System.out.print(n+" ");
    if(n==0)
        return 0;
    int result=Integer.MIN_VALUE;
    for (int i=0;i&lt;n;i++){
        result=Math.max(result,p[i]+tDRecursiveCut(p,n-i-1));
    }
    return result;
}
/*
*  自顶向下,带记忆的切割 top down
*  @param p: 收益数组
*  @param n: 待切割的长度
*  @param r:  收益记忆数组
* */
public static int tDRecursiveCutWithMemory(int[] p,int n,int[] r){
    if(r[n]&gt;=0){
        return r[n];
    }
    System.out.print(n+" ");
    int result=Integer.MIN_VALUE;
    if(n==0)
        result=0;
    else {
        for (int i = 0; i &lt; n; i++) {
            result = Math.max(result, p[i] + tDRecursiveCutWithMemory(p, n - i - 1, r));
        }
    }
    r[n]=result;
    return result;
}
/*
*  自底向上,非递归切割 bottom up
*  @param p: 收益数组
*  @param n: 待切割的长度
*  @param c:  切割方案
* */
public static int bUNonRecursive(int[] p,int n,int[] c){
    int result;
    int[] r=new int[n+1];
    int rn=r.length;
    r[0]=0;
    c[0]=0;
    for(int i=1;i&lt;rn;i++){
        result=Integer.MIN_VALUE;
        for(int j=0;j&lt;i;j++){
            if(result&lt;p[j]+r[i-j-1]) {
                result = p[j] + r[i - j - 1];
                c[i]=j+1;
            }
        }
        r[i]=result;
    }
    return  r[n];
}
public static void main(String[] args){
  Scanner in=new Scanner(System.in);
  int  n=in.nextInt();
  int[] p=new int[n];
  for(int i=0; i&lt;n;i++){
       p[i]=in.nextInt();
  }
    int toCut=in.nextInt();
    int[] r=new int[toCut+1];
    int[] c=new int[toCut+1];
    for(int i=r.length-1;i&gt;=0;i--){
        r[i]=Integer.MIN_VALUE;
    }
    int value;
    //value=tDRecursiveCut(p,toCut);
    //value=tDRecursiveCutWithMemory(p,toCut,r);
    value=bUNonRecursive(p,toCut,c);
    System.out.print("切割方案:");
    while(toCut&gt;0){
        System.out.print(c[toCut]+" ");
        toCut=toCut-c[toCut];
    }
    System.out.printf("\r\n最优切割受益:%d,耗时:%d",value,0);
}

}


相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    第一篇关于算法的博客,后续还会写各种算法题解!

waert
过去的经历必定留下无痕的印记!

推荐标签 标签

  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    116 引用 • 99 回帖 • 266 关注
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    228 引用 • 1450 回帖
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    172 引用 • 990 回帖
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    51 引用 • 37 回帖
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 692 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    148 引用 • 257 回帖 • 1 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 563 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖 • 1 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    108 引用 • 54 回帖
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 250 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    284 引用 • 4481 回帖 • 656 关注
  • OnlyOffice
    4 引用 • 28 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    124 引用 • 580 回帖
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1083 引用 • 3461 回帖 • 287 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    15 引用 • 7 回帖 • 9 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 628 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    75 引用 • 145 回帖
  • 笔记

    好记性不如烂笔头。

    303 引用 • 777 回帖
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    535 引用 • 672 回帖 • 2 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 398 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 19 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    28 引用 • 108 回帖 • 3 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    14 引用 • 7 回帖 • 1 关注
  • 分享

    有什么新发现就分享给大家吧!

    242 引用 • 1746 回帖 • 1 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖 • 3 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 5 关注