钢条切割(动态规划)

算法导论第15章:

假设公司出售一段长度为i英寸的钢条的价格为Pi(i = 1, 2, ...单位:美元),下面给出了价格表样例:

长度i     1     2     3

4  5   6     7  8   9  10

价格Pi  1     5     8

9  10   17   17  20   24  30

切割钢条的问题是这样的:给定一段长度为n英寸的钢条和一个价格表Pi,求切割方案,使得销售收益Rn最大。

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

对于上述价格表样例,我们可以观察所有最优收益值Ri及对应的最优解方案:

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(无切割)

更一般地,对于Rn(n >= 1),我们可以用更短的钢条的最优切割收益来描述它:

Rn = max(Pn, R1 + Rn-1, R2 + Rn-2,...,Rn-1 + R1)

首先将钢条切割为长度为i和n - i两段,接着求解这两段的最优切割收益Ri和Rn - i

(每种方案的最优收益为两段的最优收益之和),由于无法预知哪种方案会获得最优收益,

我们必须考察所有可能的i,选取其中收益最大者。如果直接出售原钢条会获得最大收益,

我们当然可以选择不做任何切割。

分析到这里,假设现在出售8英寸的钢条,应该怎么切割呢?

 1 #include <iostream>
 2 using namespace std;
 3 #define INF (1<<30)
 4 const int  N=10000;
 5 int r[N];
 6 int p[11]= {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
 7 int max(int a,int b)
 8 {
 9 if(a>b)return a;
10 else return b;
11 }
12 int get(int n)
13 {
14     r[0]=0;
15     for(int j=1;j<=n;j++)
16     {
17         int q=-INF;
18         for(int i=1;i<=j;i++)
19         {
20         q=max(q,p[i]+r[j-i]);
21         }
22         r[j]=q;
23     }
24 return r[n];
25 }
26 int main()
27 {
28     int n;
29 while(cin>>n)
30 cout<<get(n)<<endl;
31
32 }
时间: 2024-10-09 21:50:06

钢条切割(动态规划)的相关文章

动态规划之钢条切割

动态规划方法通常用来求解最优化问题.动态规划算法设计步骤: 1.刻画一个最优解的结构特征. 2.递归定义最优解的值. 3.计算最优解的值,通常采用自底向上的方法. 4.利用计算出的信息构造一个最优解. 动态规划的实现方法: 带备忘的自顶向下法:此方法仍按自然的递归形式编写过程,但过程会保存每个子问题的解(通常保存在一个数组或散列表中).当需要一个子问题的解时,过程首先检查是否已经保存过此解.如果是,则直接返回保存的值,从而节省了计算时间:否则,按通常方式计算这个子问题. 自底向上法:这种方法一般

《算法导论》中动态规划求解钢条切割问题

动态规划算法概述 动态规划(dynamic programming)1是一种与分治方法很像的方法,都是通过组合子问题的解来求解原问题.不同之处在于,动态规划用于子问题重叠的情况,比如我们学过的斐波那契数列.在斐波那契数列的求解问题中,我们经常要对一个公共子问题进行多次求解,而动态规划算法,则对每个子问题只求解一次,将其解保存在一个表格中,从而避免了大量的冗余计算量. 动态规划算法常用于寻找最优解问题(optimization problem).而其规划大概可分为四步: 1.刻画一个最优解的结构特

算法导论--动态规划(钢条切割)

钢条切割问题 现有一段长度为n英寸的钢条和一个价格表pi,求切割方案使销售利益最大rn最大 长度为n英寸的钢条共有2n?1种不同的切割方案,因为可以每个整英寸的位置都可以决定切割或者不切割. 为了得到rn最大,可以把这个问题分成子问题求解,先切一刀,再考虑余下的部分的最大收益即求 rn=max{pk+rn?k}(k=1,2,3-n-1), pk部分不进行继续切割,直接作为一个整体售出 ; rn?k部分继续切割,考虑所有的情况,分成子问题. 求出所有k值对应的收益最大者作为rn 也有可能不进行任何

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

动态规划通常用于解决最优化问题,在这类问题中,通过做出一组选择来达到最优解.在做出每个选择的同时,通常会生成与原问题形式相同的子问题.当多于一个选择子集都生成相同的子问题时,动态规划技术通常就会很有效,其关键技术就是对每个这样的子问题都保存其解,当其重复出现时即可避免重复求解. 钢条切割问题 Serling公司购买长钢条,将其切割为短钢条出售.切割工序本身没有成本支出.公司管理层希望知道最佳的切割方案.假定我们知道Serling公司出售一段长为i英寸的钢条的价格为pi(i=1,2,…,单位为美元

动态规划 钢条切割问题

#include <stdio.h> /* *钢条切割问题: *问题描述 假设公司出售一段长度为i英寸的钢条的价格为Pi(i = 1, 2, ...单位:美元),下面给出了价格表样例: 长度i 1 2 3 4 5 6 7 8 9 10 价格Pi 1 5 8 9 10 17 17 20 24 30 切割钢条的问题是这样的:给定一段长度为n英寸的钢条和一个价格表Pi,求切割方案,使得销售收益Rn最大. */ //假定价格一开始已经给出了,用全局的写死 #define max(x,y) (x)>

动态规划 -- 钢条切割

/* 动态规划和分治法相似,都是通过组合子问题的解来求解原问题. 但分治法是将 问题划分为互不相交的子问题,递归地求解子问题,再将它们的解组合起来,求出 原问题的解.与之相反,动态规划应用于子问题重叠的情况,即不同的子问题具有公共的 子问题.在这种情况下,分治法会做很多不必要的工作. 动态规划方法通常用来求解最优化问题,这类问题通常有很多可行解.我们希望寻找 具有最优值的解. 我们通常按照如下4个步骤来设计一个动态规划算法: · 刻画一个最优解的结构特征 · 递归地定义最优解的值 · 计算最优解

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

动态规划方法通常用来求解最优化问题.动态规划算法设计步骤: 1.刻画一个最优解的结构特征. 2.递归定义最优解的值. 3.计算最优解的值,通常采用自底向上的方法. 4.利用计算出的信息构造一个最优解. 动态规划的实现方法: 带备忘的自顶向下法:此方法仍按自然的递归形式编写过程,但过程会保存每个子问题的解(通常保存在一个数组或散列表中).当需要一个子问题的解时,过程首先检查是否已经保存过此解.如果是,则直接返回保存的值,从而节省了计算时间:否则,按通常方式计算这个子问题. 自底向上法:这种方法一般

动态规划学习笔记--对于钢条切割方案的思考

1.问题描述 对一个长为n的钢条,给出不同长度钢条对应的单价,求出如何切割能使得该钢条的收益最大化. 2.问题解析 (1)暴力法 找出所有切割方案(共2^(n-1)种),计算出每种切割方案的收益,求最大值. 时间复杂度:O(2^(n-1)) (2)动态规划 这一问题是<算法导论>中,讲解动态规划的例题. 为什么这题能够用动态规划解决呢? 动态规划是用来解决具有以下性质的问题的: 1.最优子结构 2.重复子问题 这两个性质,显然前者更为重要,而后者没有也可以用动态规划解决(我现在这么认为). 动

第十五章 动态规划——钢条切割

前言:动态规划的概念 动态规划(dynamic programming)是通过组合子问题的解而解决整个问题的.分治算法是指将问题划分为一些独立的子问题,递归的求解各个问题,然后合并子问题的解而得到原问题的解.例如归并排序,快速排序都是采用分治算法思想.本书在第二章介绍归并排序时,详细介绍了分治算法的操作步骤,详细的内容请参考:http://www.cnblogs.com/Anker/archive/2013/01/22/2871042.html.而动态规划与此不同,适用于子问题不是独立的情况,也

动态规划 钢条切割问题的朴素解法

第一版代码 : #include <iostream> using namespace std; int max(int a,int b) { if(a>=b)return a; else return b; } int cut_rod(int *p,int n) { int q=NULL; if(n==0)return 0; else for(int i=0;i<n;i++) { q=max(q,p[i]+cut_rod(p,n-1-i)); } return q; } int