关闭

动态规划:钢条切割问题实现

标签: 动态规划非递归钢条切割
502人阅读 评论(0) 收藏 举报
分类:

钢条切割问题是这样的:

一段钢条可以被切割成若干长度不一的更短的钢条,给定一个价目表,问如何切割收益最大。其中价目表包括了长度为从i=1到i=n的钢条分别的价格Pi。比如P1=1,P2=5表示长度为1的钢条的价值为1,长度为2的钢条的价值为5。


这是一个典型的动态规划问题。

第一种方法是自顶向下的方法,假定我们已经知道了长度为K的钢条的最大收益,然后通过这个最大收益求解长度为K+1的钢条的最大收益。因此我们递归地定义了钢条的最大收益。虽然思想是由小求大,但是实际程序需要我们由顶向下求解。代码如下:

#include <iostream>
#include <stdio.h>
#include <memory.h>
#define N 100
int prices[N];              //长度为n的钢条的价格
int r[N];                   //长度为n时的最大收益
int cut_rod(int n);         //求最大收益
int answer[N];              //保存切割位置

int main()
{
    int n;
    while(1 == scanf("%d", &n))
    {
        memset(answer, 0, sizeof(answer));
        memset(r, -1, sizeof(r));
        for(int i = 1; i <= n; ++i)
            scanf("%d", &prices[i]);

        printf("%d\n", cut_rod(n));
    }
    return 0;
}

/* 自顶向下的递归求解算法 */
int cut_rod(int n)
{
    if(r[n] > 0)    //如果已经算过,直接返回
        return r[n];
    int temp = -1;
    if(0 == n)      //长度为0的钢条价格为0
        temp = 0;
    //下面的循环递归求解长度为n的钢条的最大收益
    for(int i = 1; i <= n; ++i)
    {
        int x = prices[i] + cut_rod(n - i);
        if(x > temp)
            temp = x;
    }
    r[n] = temp;
    return temp;
}
这种方法可以求得最大收益,但是构建最优切割方案是个麻烦的事情,所以还有一种非递归的方法,在求解最优子问题的同时,逐步构建了最优方案。


这种非递归的方法的思想和上面的思想相同,即由短求长,但是采用了非递归的方法。代码如下:

#include <iostream>
#include <stdio.h>
#include <memory.h>
#define N 100
int prices[N];                          //长度为n的钢条的价格
int r[N];                               //长度为n时的最大收益
int cut_rod_bottom_up(int n);           //求最大收益
int answer[N];                          //保存切割位置

int main()
{
    int n;
    while(1 == scanf("%d", &n))
    {
        memset(answer, 0, sizeof(answer));
        memset(r, -1, sizeof(r));
        for(int i = 1; i <= n; ++i)
            scanf("%d", &prices[i]);

        printf("%d\nBest Cut:", cut_rod_bottom_up(n));
        int x = 0;
        //输出最优方案的切割位置
        while(n > 0)
        {
            x += answer[n];
            printf("%d ", x);
            n = n - answer[n];
        }
        printf("\n");
    }
    return 0;
}
/* 自底向上的非递归求解算法 */
int cut_rod_bottom_up(int n)
{
    r[0] = 0;
    for(int i = 1; i <= n; ++i)
    {
        int x = 0;
        //下面的循环,求解长度为i的钢条的最大收益
        for(int j = 1; j <= i; ++j)
        {
            if(prices[j] + r[i-j] > x)
            {
                x = prices[j] + r[i-j];
                answer[i] = j;              //存储长度为i的钢条的左边的第一个切割位置
            }
        }
        r[i] = x;   //储存长度为i的钢条的最佳收益
    }
    return r[n];
}



1
0
查看评论

动态规划--钢条切割问题

动态规划法(dynamic programming),这里的programming不是编程的意思,而是一种表格法 不同于前面的分治法,是把问题分成若干互不相交的小问题,递归的解决这些问题,然后合并解决大问题,当各个小问题是重叠的时,分治法会做很多重复的计算,会反复求解公共子问题,而动态规划会把公共...
  • BeforeEasy
  • BeforeEasy
  • 2016-07-31 21:11
  • 716

动态规划:钢条切割问题

动态规划与分治法相似,都是通过组合子问题的解来求解原问题。回顾下分治法的原理:它将问题划分为互不相交的子问题(注意:互不相交),递归求解子问题,再将它们的解组合起来,即为原问题的解。        但是,动态规划与分治法不同,有以下几点: 1)对于子问题重...
  • u013165521
  • u013165521
  • 2015-07-17 20:56
  • 570

动态规划算法——钢条切割问题

动态规划是通过组合子问题的解来求解原问题。与分治方法不同的是,动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子子问题。在这种情况下,分治策略会重复的计算那些公共子问题。而动态规划是对每个子子问题只求解一次,将其保存在一个表格中,从而避免重复计算这些问题。 动态规划通常用于求解最优化问题(...
  • nxiangbo
  • nxiangbo
  • 2016-04-10 10:08
  • 984

动态规划--钢条切割的C++实现

在《算法导论》动态规划那章,讲述了一个应用动态规划的例子--钢条切割。 钢条切割的问题是这样的:给定一段长度为n英寸的钢条和一个价格表(i=1,2,...,10),求切割钢条方案,使得销售收益最大。 我们可以采用一种简单的递归求解方法:我们将钢条从左边切割下长度为i的一段,只对右边剩下的 长度为n-...
  • u010051302
  • u010051302
  • 2013-11-14 17:09
  • 1181

算法导论:动态规划 切钢条问题

问题描述:不同长度的钢条,具有不同的价值,而切割工序没有成本支出,公司管理层希望知道最佳切割方案,假定钢条的长度均为整数:用数组v[I]表示钢条长度为I所具有的价值v[] = {0,1,5,8,9,10,17,17,20,24,30};用r[I]表示长度为I的钢条能获取的最大价值,通过观察可以知道,...
  • chen_minghui
  • chen_minghui
  • 2016-11-05 11:18
  • 641

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

动态规划方法通常用来求解最优化问题。动态规划算法设计步骤: 1.刻画一个最优解的结构特征。 2.递归定义最优解的值。 3.计算最优解的值,通常采用自底向上的方法。 4.利用计算出的信息构造一个最优解。 动态规划的实现方法: 带备忘的自顶向下法:此方法仍按自然的递归...
  • chenxun2009
  • chenxun2009
  • 2014-12-13 01:30
  • 1375

动态规划-钢条切割(java)

数据结构与算法系列源代码:https://github.com/ThinerZQ/AllAlgorithmInJava 本文源代码:https://github.com/ThinerZQ/AllAlgorithmInJava/blob/master/src/main/java/com/zq/alg...
  • c601097836
  • c601097836
  • 2015-11-25 21:45
  • 1112

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

一、综述 动态规划是通过组合子问题的解而解决整个问题的。 动态规划适用于子问题不是独立的情况,也就是各子问题的包含公共的子子问题。 动态规划对每个子问题只求解一次,将其结果保存在一张表中。 动态规划通常用于最优化问题。 动态规划的设计步骤:a.描述最优解的结构b.递归定义最优解的值c.按自...
  • u012243115
  • u012243115
  • 2014-11-07 08:31
  • 900

[算法学习笔记]动态规划之钢条切割问题

问题描述有一个长度为n的钢条需要切割成短钢条出售,长度不同的钢条售价也不同,如下: 长度i 1 2 3 4 5 6 7 8 9 10 价格p[i] 1 5 8 9 10 17 17 20 24 30 那么怎么切割才...
  • u014235934
  • u014235934
  • 2016-08-05 14:10
  • 507

动态规划与钢条切割问题 C++实现

动态规划一、原理我们可以用拉格朗日乘数法,求解给定条件下的方程最优解,同样,动态规划算法也是用于在一定条件下的求解最优解的方法。它和分治方法很相似,都是通过组合子问题来求解原问题。一般适用于动态规划算法的问题具备两个条件:最优子结构和重叠子问题。考虑一般的递归算法,总是会重复调用问题的子结构,来解决...
  • liu798675179
  • liu798675179
  • 2016-11-01 19:50
  • 745
    联系我
    交流或者提问请加入QQ群:532232743
    个人资料
    • 访问:186617次
    • 积分:3081
    • 等级:
    • 排名:第13453名
    • 原创:124篇
    • 转载:2篇
    • 译文:0篇
    • 评论:58条
    博客专栏
    最新评论