zoukankan      html  css  js  c++  java
  • 动态规划之钢条切割

    问题导入

    假定某公司购买长钢条,将其切割为短钢条进行出售(切割工序本身没有成本支出)。考虑求出最佳的切割方案。

    出售一段长度为i的钢条价格如下表:

    长度i 价格p
    1 1
    2 5
    3 8
    4 9
    5 10
    6 17
    7 17
    8 20
    9 24
    10 30

    时间复杂度

    长度为n的钢条共有2的n-1次方种不同的切割方案,因为在距离钢条左端i处,总是可以选择切割或不切割。所以普通方法(递归)解决此问题的时间复杂度为2的指数级别。

    普通方法效率很低,是因为它反复求解相同的子问题

    动态规划则仔细安排求解顺序,对每个子问题只求解一次,并将结果保存下来。如果随后再次需要求解此子问题的解,只需查找保存的结果,而不必重新计算。因此,动态规划是付出额外的内存空间来节省计算时间。而时间上的节省可能是非常巨大的。

    动态规划原理

    动态规划与分治方法相似,都是通过组合子问题的解来求解原问题。

    适合使用动态规划方法求解的最优化问题应该具备两个要素:

    1.最优子结构:如果一个问题的最优解包含其子问题的最优解,就称此问题具有最优子结构轻型纸。

    2.子问题重叠:问题的递归算法会反复地求解相同的子问题,而不是一直产生新的子问题。

    问题求解

    public class Cut {
        public static void main(String[] args) {
            //钢条价格数组
            int[] p = {1,5,8,9,10,17,17,20,24,30};
            method(p, 10);
        }
        public static void method(int[] p, int n){
            //结果数组
            int[] r = new int[n+1];
            //切割方式数组
            int[] s = new int[n+1];
            for(int j = 1;j <= n;j++){
                int q = -1;     //此处-1的作用是"无穷小"
                for(int i = 1;i <= j;i++){
                    if(q < p[i-1]+r[j-i]){
                        q = p[i-1]+r[j-i];
                        s[j] = i;   //表示长度为j时,被切割后的左部分长度为i,而右部分如何切割则递归查找s数组
                        r[j] = q;   //长度为j时的最大收益值
                    }
                }
            }
            for (int count = 0;count <= n;count++){
                System.out.println(r[count]);
                System.out.println(s[count]);
            }
        }
    }
    

    算法主体部分为两层for循环,因此用动态规划解决此问题的时间复杂度为n的平方。

  • 相关阅读:
    bat批处理脚本学习系列(一)
    遇到的bug
    util.js 积累的一些基础函数代码
    session过期跳转到登陆页面并解决跳出iframe问题
    Centos7下的rabbitmq-server-3.8.11安装配置
    简单梳理 ES6 函数
    博客目录与学习计划
    DDD中聚合、聚合根的含义以及作用
    DDD中实体与值对象是干什么的
    DDD中限界上下文与通用语言的作用
  • 原文地址:https://www.cnblogs.com/cky-2907183182/p/12184593.html
Copyright © 2011-2022 走看看