一、问题引入

有一根长度为L(L < 1000)的木棍,还有n(n < 50)个切割点的位置(按照从小到大排列)。你的任务是在这些切割点的位置处把棍子切成n+1份,使得总费用最小。每次切割的费用等于被切割的木棍长度。

二、问题分析

这个问题很像前面的栅栏维修(给定n个木棍的长度,切割点任意),这道题目相当于给定n+1个木棍的长度,且切割点固定。之前的贪心法就不能适用,因为用贪心法需要切割的点不一定是给定的切割点。我们必须换一种思路了。

n的规模非常小,可以考虑枚举切割点,但直接枚举所有的切割顺序肯定太大,可以考虑动态规划,枚举切割第一刀的位置。

设d(i,j)为切割小木棍i~j的最优费用,则d(i,j) = min{(d(i,k),d(k,j)) | i < k < j} + a[j] - a[i],其中a[j] - a[i]代表第一刀的费用。

注意,这里i,j都是表示切割点的位置,而不是木棍的序号,这样比较方便。

三、代码实现

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6
 7 const int INF = 0x3f3f3f3f;
 8 const int maxl = 1000 + 10;
 9 const int maxn = 50 + 10;
10 int L, n, cutp[maxn];
11 int d[maxn][maxn];    //d[i][j]表示切割小木棍i-->j的最小费用,i,j表示的是切割点,d[0][n + 1]为所求
12
13 void slove()
14 {
15     for (int i = n + 1; i >= 0; i--)        //注意循环顺序,这里必须是从大到小
16         for (int j = i; j <= n + 1; j++)    //这里必须从小到大,这个观察状态转移方程就可以了
17         {
18             d[i][j] = (i + 1 == j ? 0 : INF);
19             for (int k = i + 1; k < j; k++)
20                 d[i][j] = min(d[i][j], d[i][k] + d[k][j] + cutp[j] - cutp[i]);
21         }
22     printf("The minimum cutting is %d.\n", d[0][n + 1]);
23 }
24
25 int main()
26 {
27     while (scanf("%d", &L) == 1 && L)
28     {
29         scanf("%d", &n);
30         for (int i = 1; i <= n; i++)
31             scanf("%d", &cutp[i]);
32
33         //左边界编号为0,右边界为 n + 1
34         cutp[0] = 0; cutp[n + 1] = L;
35
36         slove();
37     }
38     return 0;
39 }

四、总结

这种解法,状态有O(n2),每种状态有O(n)个决策,时间复杂度为O(n3)。据说可以用四边形不等式优化到O(n2),以后会了再补充吧。

转载于:https://www.cnblogs.com/lfri/p/9458060.html

木板切割问题(二)——动态规划相关推荐

  1. 木板切割最优matlab,矩形木板最优切割方案的设计与实现

    邹涵 李涛 朱婷婷 摘要:本文所设计的最优切割方案使用了回溯法和递归算法对最优切割问题进行划分,使木板最优切割问题转化为不同切割方式下木板的最大利用率问题,同时根据切割要求对切割方案进行优化,选择最优 ...

  2. 【挑战程序设计竞赛】- 2.2贪心法(硬币最少、区间覆盖、字典序最小、标记最少、木板切割)

    四年前犯的错再做一遍还是会犯. 四年前不看presentation要求,四年后依然PE. 四年前忘记longlong,四年后还是会忘. 2.2 贪心法 核心思想:不断选取最优策略. 例题1-硬币:有1 ...

  3. 木板切割问题——贪心

    一.问题引入 农夫约翰为了修理栅栏,要将一块很长的木块切成N块.准备切成的长度分别是L1.L2...,LN,未切割前的木板长度切好为切割后木板长度的总和.每次切断木板时的开销是这块木板的长度.(1 ≤ ...

  4. 算法实验二 动态规划

    动态规划1 实验题目:减肥的小K2 题目描述: 小K是个苦命的孩子,他的师傅为了多赚钱,以减肥为理由,让他去采药,并说不完成不能吃饭.野地里有许多不同的草药,采每一株都需要一些时间,每一株也有它自身的 ...

  5. 实验二 动态规划算法 最大字段和问题

    基本题二:最大字段和问题 一.实验目的与要求 1.熟悉最长最大字段和问题的算法: 2.进一步掌握动态规划算法: 二.实验题 若给定n个整数组成的序列a1,a2,a3,...,an,求该序列形如ai+a ...

  6. 算法分析与设计-实验二 动态规划算法设计

    文章目录 1. 数字三角问题 2.最长公共子序列问题 3.日常购物 4.台阶问题 一.实验目的: 掌握动态规划算法的基本思想及适用条件,掌握动态规划算法的设计步骤和具体实现. 二.实验所用仪器及环境 ...

  7. 五大算法之二--动态规划

    动态规划--简单的理解 这个算法简单的来讲就是采用自底向上的方式递推求值,将待求解的问题分解成若干个子问题,先求解子问题,并把子问题的解存储起来以便以后用来计算所需要求的解.简言之,动态规划的基本思想 ...

  8. 数据结构(十二)动态规划

    1 递归函数建模 动态规划一般用于全局问题,在构造递归的时候,一般采用自顶向下分解的方法,先把全局问题分解成更小的子问题求解.下面举两个例子 例子1:有一座高度是10阶的楼梯,从下往上走,每跨一步可以 ...

  9. 实验二 动态规划算法 最长公共子序列问题

    基本题一:最长公共子序列问题 一.实验目的与要求 1.熟悉最长公共子序列问题的算法: 2.初步掌握动态规划算法: 二.实验题 若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,z ...

最新文章

  1. 全屏四摄颜值王荣耀9青春版炫美开售 1199元起
  2. 机房管理系统——vb与excel链接2
  3. 测试CPU品牌和当前工作频率
  4. 可以直接考信息系统项目管理师吗
  5. netbeans快捷键
  6. HDU 2112 HDU Today lt;SPFA算法+map函数gt;
  7. 【C++深度剖析教程8】C++的操作符重载的概念
  8. linux c 将虚拟地址转化为物理地址_面试不懂 Linux 内存管理?我用 20 张图给你讲明白...
  9. python三引号解析_[宜配屋]听图阁
  10. Linux 正则表达式 流编辑之sed awk
  11. 《C#多线程编程实战(原书第2版)》——3.6 在线程池中使用等待事件处理器及超时...
  12. matlab 电机 热仿真,MATLAB在电机仿真中的应用
  13. Transformer 真的很全能!谷歌用协同训练策略实现多个SOTA,单一ViT模型执行多模态多任务...
  14. python实现去除图片水印
  15. C#彩色艺术化二维码样式设计(仅说思路)
  16. sketchup画圆柱面
  17. 红米max86怎么样 有什么优缺点
  18. LikeLib区块链底层公链技术应用
  19. 国内CMS内容管理系统
  20. DT(密集轨迹)算法和iDT(改善的密集轨迹)算法

热门文章

  1. springboot+jpa+mysql Springboot+jpa+jdbc+sqlserver 使用时遇到的一系列的问题
  2. TNS-12535,TNS-00505,ORA-3136报错信息处理
  3. ApkScan-PKID查壳工具+脱壳(搬运)
  4. 【用户画像】实现宽表合并,pivot概述,源码实现并发布任务
  5. 揭秘“菲住布渴”中运用的黑科技:除了check in、坐电梯、开门...全部刷脸之外,还有什么?...
  6. 萌新linux的基础笔记
  7. cocos creator 设置开启canvas 透明后 半透明图片 不正常的 官方解决办法
  8. 挣值管理名词(EV、AC、PV等)与公式详解
  9. unity软粒子softparticle仿真实现
  10. 自定义悬浮球,提供一些快捷操作。比如一键静音,一键锁频,一键截屏,一键回桌面,手电筒等