当前位置: 首页 > news >正文

钢条切割(动态规划)

递归求解

钢条切割问题是《算法导论》上动态规划部分的第一个例题。这里就以算法导论上的例子来讨论这个问题。

 例如当我们切割n=4的钢条时,切割情况如下:

 用递归方法解决这个问题时,代码如下(以n=4为例):

#include <bits/stdc++.h>
using namespace std;// 价格数组
int val[11] = {0,1,5,8,9,10,17,17,20,24,30};int cut_rod(int p[],int n)
{if(n == 0) return 0; // 边界条件int q = -1;for(int i = 1;i <= n;i++)q = max(q,p[i]+cut_rod(p,n-i));return q;
}int main()
{cout << cut_rod(val,4) << endl;return 0;
}

其中 for(int i = 1;i <= n;i++) q = max(q,p[i]+cut_rod(p,n-i)) :

p[i]+cut_rod(p,n-i)为前 i 个长度不切割,后面 n-i 个长度切割所能取得的最大值。

动态规划求解

实际运行的时候我们会发现当n的规模偏大的时候,再使用递归的话,程序很有可能超过一个小时的运行时长。所以我们展示如何将这个钢条切割问题转换为一个更高效的动态规划算法。

朴素递归算法之所以效率很低,是因为它反复求解相同的子问题。因此动态规划方法仔细安排求解顺序,对每个子问题只求解一次,并将结果保存下来。所以我们看出:动态规划是付出额外的空间来节省计算时间。

这一题可以用一个数组 f[] ,其中 f[i] 表示长度为 i 的钢条能得到的最大的价值。因此状态转移方程就能写为:

 其中,val(j) 表示前 j 个长度不切割的钢条的价值。

代码实现:

#include <bits/stdc++.h>
using namespace std;const int N = 11;int n;
int val[11] = {0,1,5,8,9,10,17,17,20,24,30}; // 价格数组
int f[N];int main()
{n = 10;for(int i = 1;i <= n;i++){for(int j = 1;j <= i;j++){f[i] = max(f[i],val[j]+f[i-j]);}}cout << "最大价值:" << f[n] << endl;return 0;
}

运行结果:

构造最优解

我们还可以拓展动态规划算法,使之对每个子问题不仅保存最大价值,而且给出切割方案。

对于长度为j的钢条,我们保存最优解对应的第一段钢条的切割长度x[j]。接着就可以循环求出长度为j-x[j]的切割方案。

代码实现:

#include <bits/stdc++.h>
using namespace std;const int N = 11;int n;
int val[11] = {0,1,5,8,9,10,17,17,20,24,30}; // 价格数组
int f[N];
int x[N];int main()
{n = 10;for(int i = 1;i <= n;i++){for(int j = 1;j <= i;j++){if(f[i] < val[j]+f[i-j]) x[i] = j; // 记录第一次切割的长度f[i] = max(f[i],val[j]+f[i-j]);}}cout << "最大价值:" << f[n] << endl;// 构造最优解cout << "切割方案:";int ll = n;while(ll > 0){cout << x[ll] << " ";ll -= x[ll];}cout << endl;return 0;
}

运行结果:

http://www.dtcms.com/a/207466.html

相关文章:

  • gcc版本选择和软链接gcc
  • 【工具】Quicker/VBA|PPT 在指定位置添加有颜色的参考线
  • 基于江协标准库所出现的定时器5678以及串口45等无法使用的问题解析
  • centos8 配置网桥,并禁止kvm默认网桥
  • Tomcat优化
  • LESS基础用法详解
  • 现代健康养生指南
  • 进销存管理系统:Java+Vue,含源码及文档,集成采购、销售、库存管理,实现数据互通,提升运营效率
  • 场景化应用实战系列六:检索问答系统
  • 力扣HOT100之二叉树: 236. 二叉树的最近公共祖先
  • ros2 多线程节点调度MultiThreadedExecutor
  • C++线程池----基于生产者消费者模式队列实现
  • 多元回归的假设检验
  • 算法题(153):哈夫曼编码
  • ArkTs中的尾随闭包
  • Linux系统:基础命令之 ls~pwd~cd
  • scratch课后一练--事件模块
  • 操作系统结构
  • Java字节码文件解析
  • 101个α因子#25
  • android:exported=“true“的作用
  • 【DAY26】函数专题1:函数定义与参数
  • 软考高项考前48小时冲刺:核心考点记忆 + 错题复盘 + 3 科重点
  • 先进先出(FIFO)页面置换算法
  • CentOS7安装 PHP-FPM 7.4
  • git@gitee.com: Permission denied (publickey). fatal: 无法读取远程仓库
  • 基于单片机的室内采光及可燃气体泄漏报警装置设计
  • FastAPI在 Nginx 和 Docker 环境中的部署
  • 深入理解线程池:参数、流程与实战应用
  • Qt控件:输入控件