算法导论 15.1 钢条切割

这里对这个DP问题做了代码实现,分为递归算法(自顶向下)和非递归算法(自下向上),以及拓展的自下向上算法的实现。

递归算法:

 1 #include<iostream>
 2
 3 using namespace std;
 4
 5 int size = 10;
 6
 7 inline int max(int a, int b)
 8 {
 9     return a > b ? a : b;
10 }
11
12 int CutRod(int p[], int n)
13 {
14     if (n == 0)
15         return 0;
16     else
17     {
18         int q = INT_MIN;
19         for (int i = 1; i < n; i++)
20         {
21             q = max(q, p[i] + CutRod(p, n - i -1));
22         }
23         return q;
24     }
25 }
26
27
28
29 int main()
30 {
31     int a[] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };
32     cout << CutRod(a, 6) << endl;
33 }

非递归算法:

#include<iostream>

using namespace std;

int size = 10;

inline int max(int a, int b)
{
    return a > b ? a : b;
}

int NonRecursionCutRod(int p[], int n)
{
    int *r = new int[n];
    r[0] = p[0];
    for (int j = 1; j < n; j++)
    {
        int q = p[j];
        for (int i = 0; i < j; i++)
        {
            if (q<(p[i] + r[j - i - 1]))
            {
                q = p[i] + r[j - i - 1];
            }
        }
        r[j] = q;
    }
    return r[n-1];
}

int main()
{
    int a[] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };
    cout << NonRecursionCutRod(a, 6) << endl;
}

拓展非递归算法:

这里我建立了一个Result Struct用来作为返回结果,其实这个的意图:假如我们要求长度为j的解决方案,那么我们就在数组下标为j的单元中存上切割的第一段的长度,假如为i,那么剩下的部分可以通过去寻找j-i的方案,这样递归下去就可以得到长度为j的解决方案了。

 1 #include<iostream>
 2
 3 using namespace std;
 4
 5 typedef struct Result
 6 {
 7     int Max;
 8     int *Price;
 9 }Result;
10
11 Result ExtendNonRecursionCutRod(int a[], int n)
12 {
13     Result result;
14     result.Price = new int[n+1];
15     int *r = new int[n+1];
16     r[1] = a[1];
17     result.Price[1] = a[1];
18     for (int j = 1; j <= n; j++)
19     {
20         int q = a[j];
21         int t = j;
22         for (int i = 1; i < j; i++)
23         {
24             if (q < (a[i] + r[j - i]))
25             {
26                 q = a[i] + r[j - i];
27                 t = i;
28             }
29         }
30         r[j] = q;
31         result.Price[j] = t;
32     }
33     result.Max = r[n];
34     return result;
35 }
36
37 int main()
38 {
39     int a[] = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };
40     Result  result = ExtendNonRecursionCutRod(a, 10);
41     cout << result.Max << endl;
42     for (int i = 1; i < 10; i++)
43         cout << result.Price[i] << "    ";
44 }
时间: 2024-08-09 22:00:46

算法导论 15.1 钢条切割的相关文章

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

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

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

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

MIT:算法导论——15.动态规划

[设计一个动态规划算法的四个步骤] 1.刻画一个最优解的特征. (最优子结构?!) 2.递归地定义最优解的值. 3.计算最优解的值,通常采用自底向上方法. 4.利用计算出的信息构造一个最优解. 适合动态规划方法求解的最优化问题需要具备的两个性质: [最优子结构(optimal substructure)] 问题的最优解由相关子问题的最优解组合而成,而这些子问题可以独立求解.(动态规划具体实现之处) [重叠子问题(overlapping subproblem)] 如果递归算法反复求解相同的子问题,

算法导论动态规划 15.1-3 钢条切割问题

算法导论的第一个动态规划问题--钢条切割 我们知道钢条的长度和价格为: 长度i 1 2 3 4 5 6 7 8 9 10 价格pi 1 5 8 9 10 17 17 20 24 30 书上的两种方法已经很清楚,这里主要说一下课后练习里面15-3钢条成本加上切割成本,即要切割的次数最少.15-4返回切割方案 #include<fstream> #include<iostream> using namespace std; int main() { int const N = 11;

【算法设计-动态规划】钢条切割问题

问题:给定一段长度为n英寸的钢条和一个价格表pi(i=1,2,...,n),求切割钢条方案,使得销售收益rn最大.如果长度为n英寸的钢条的价格pn足够大,最优解可能就是完全不需要切割. 方法一:递归 从上而下把所有的全部搜索一遍 int CUT_ROD(int p[],int n) { if(n==0) return 0; int q=INT_MIN; for(int i=1;i<=n;i++) { q=max(q,p[i]+CUT_ROD(p,n-i)); printf("n=%d&qu

红黑树&mdash;&mdash;算法导论(15)

1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极端情况是树变成了1条链)时,这些集合操作并不比在链表上执行的快.     于是我们需要构建出一种"平衡"的二叉搜索树.     红黑树(red-black tree)正是其中的一种.它可以保证在最坏的情况下,基本集合操作的时间复杂度是O(lgn). (2) 性质     与普通二叉搜索树不

算法导论读书笔记之钢条切割问题

算法导论读书笔记之钢条切割问题 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 给定一段长度为n英寸的钢条和一个价格表 pi (i=1,2, -,n),求切割钢条的方案,使得销售收益rn最大.注意,如果长度为n英寸的钢条价格pn足够大,最优解可能就是完全不需要切割. 若钢条的长度为i,则钢条的价格为Pi,如何对给定长度的钢条进行切割能得到最大收益? 长度i   1   2    3   4     5      6     7     8  

第15章动态规划------算法导论

15.1钢条切割 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<ctime> #include<string> using namespace std; int p[1000]{ 0,1,5,8,9,10,17,17,20,24,30 };//钢条价格.长度i的价格为p[i] int ordinary(int *p, int n)//递归法 {

算法导论第十五章动态规划

概述: 1.动态规划是通过组合子问题的解而解决原问题的. 2.动态规划适用于子问题不是独立的情况,也就是各子问题的包含公共的子子问题. 3.动态规划对每个子问题只求解一次,将其结果保存在一张表中. 4.动态规划的设计步骤:a.描述最优解的结构b.递归定义最优解的值c.按自底向上的方式计算最优觖的值d.由计算出的结构构造一个最优解 15.1钢条切割 钢条切割问题:给定定长的钢条和价格表,求切割方案,使得收益最大.如果n英寸的钢条的价格足够大,则不需要切割. 代码如下: //朴素递归求解钢条切割收益