Rod cutting problem DP
动态规划算法的一个特点就是通过记忆(memomorization), 记录下原问题的子问题的最优解(因为原始问题具有最优子结构), 从而 来避免通过递归, 重复的计算子问题。
下面, 我们首先假设我们关于不同长度的木头的价格表, 如下:
然后, 我们的目的就是通过选择切割方案使得我们的收益达到最大。
首先我们看看如何采用递归的方式解决这个问题。 一个recursive functio完全可以通过数学式子表示。
然后, 我们将我们的recursive version 通过引入memorization 来避免recursive, 即是我们的动态规划算法(dynamic programming)。递归程序如下:
#include <iostream>
#include <vector>
using namespace std;
double recurRodCutting(const vector<double>&p, int n) {
if (n < 1) return 0.0;
double Max = p[n]; //if donot cut off
for (int i = 1; i < n; i++) {
double temp = p[i] + recurRodCutting(p, n - i);
if (temp > Max) Max = temp;
}
return Max;
}
int main()
{
vector<double> prices = {1, 3, 3, 5, 5, 7, 8, 3, 10, 10};
cout << recurRodCutting(prices, 10) << endl;
return 0;
}
运行结果如下, 有问题的:
显然是有问题的,太大了, 那么问题出在哪里呢???
需要调试, 我们可以通过在程序中埋进去一些cout<< 以在输出查看结果, 或者我们也可以直接通过设置断点debug。
最终, 我们发现错误忘记了将第一个假如0 放在vector 的第一个元素了。 因为vector 的indice 是从0 开始的:
#include <iostream>
#include <vector>
using namespace std;
double recurRodCutting(const vector<double>&p, int n) {
if (n < 1) return 0.0; // base case
// cout << n << endl;
double Max = p[n]; //if do not cut off
for (int i = 1; i < n; i++) {
double temp = p[i] + recurRodCutting(p, n - i);
// cout << i << " " << temp << endl;
if (temp > Max) Max = temp;
}
return Max;
}
int main()
{
vector<double> prices = {0, 1, 3, 3, 5, 5, 7, 8, 3, 10, 10};
cout << recurRodCutting(prices, 10) << endl;
return 0;
}
运行的结果如下, 这是正确的:
上述的算法是brute force的形式, 时间复杂度达到指数级了。 很不实用。 下面我们使用dynamic programming 修改算法, 使得算法的时间复杂度降为O(n^2), 如下:
#include <iostream>
#include <vector>
using namespace std;
double recurRodCutting(const vector<double>&p, int n) {
if (n < 1) return 0.0; //base case
// cout << n << endl;
double Max = p[n]; //if do not cut off
for (int i = 1; i < n; i++) {
double temp = p[i] + recurRodCutting(p, n - i);
// cout << i << " " << temp << endl;
if (temp > Max) Max = temp;
}
return Max;
}
double dpRodCutting(const vector<double>&p2, int n) {
vector<double> r(n+1);
r[0] = 0.0;
for (int j = 1; j <= n; j++) {
double Max = p2[j];
for (int i = 1; i < j; i++) {
double temp = p2[i] + r[j - i];
if (temp > Max) Max = temp;
}
r[j] = Max;
}
// for (auto x:r) cout << x << " ";
// cout << endl;
return r[n];
}
int main()
{
vector<double> prices = {0, 1, 3, 3, 5, 5, 7, 8, 3, 10, 10};
cout << dpRodCutting(prices, 10) << endl;
return 0;
}
运行结果如下:
Rod cutting problem DP相关推荐
- 动态规划法(五)钢条切割问题(rod cutting problem)
继续讲故事~~ 我们的主人公现在已经告别了生于斯,长于斯的故乡,来到了全国最大的城市S市.这座S市,位于国家的东南部,是全国的经济中心,工商业极为发达,是这个国家的人民所向往的城市.这个到处都 ...
- 切割钢条问题(rod cutting problem)
问题描述 Seriling公司购买长钢条,将其切割为短钢条出售.切割工序本身没有成本支出.公司管理层希望知道最佳的切割方案. 假定我们知道Serling公司出售一段长为ii ii英寸的钢条的价格为pi ...
- 算法题:Rod Cutting
算法题:Rod Cutting 一.题目 二.代码 三.结果 一.题目 二.代码 lengths = [1,1,3,4] lengths = [5,4,4,2,2,8]def rodOffcut(le ...
- uva 10401 Injured Queen Problem(dp)
题目链接:10401 - Injured Queen Problem 题目大意:给出一个字符串,要求在n * n(n为字符串的长度)的棋盘上摆放n个受伤的皇后,受伤的皇后只能攻击到同一列和它周围8个格 ...
- bestcoder #56 div 2 B Clarke and problem(dp)
Clarke and problem Accepts: 169 Submissions: 372 Time Limit: 2000/1000 MS (Java/Others) Memory L ...
- acdream 1222 Quantization Problem [dp]
称号:acdream 1222 Quantization Problem 题意:给出一个序列 a ,然后给出一个 n * m 的矩阵,让你从这个矩阵中选出一个序列k,使得sum(abs(ki - ai ...
- poj 3590 The shuffle Problem——DP+置换
题目:http://poj.org/problem?id=3590 bzoj 1025 的弱化版.大概一样的 dp . 输出方案的时候小的环靠前.不用担心 dp 时用 > 还是 >= 来转 ...
- Codeforces 513G1 or 513G2 Inversions problem DP
题目大意: 就是现在初始给定一个n个数的排列, 每次随机地选取任意的一个段的数进行反转, 问k次随机翻转之后逆序对的数量的期望 G1难度题目链接:http://codeforces.com/conte ...
- [CF1153F]Serval and Bonus Problem(dp/积分+OGF)
其实这道题已经在我的学习笔记里面口胡过了- 但由于某种特殊原因-我写了一篇博客. 题面 Getting closer and closer to a mathematician, Serval bec ...
最新文章
- 在 DW 中插入 Flash 的参数详解
- 配置Keil C51配置开发 STC51单片机过程
- 成功解决You are using pip version 9.0.3, however version 10.0.1 is available. You should consider upgr
- Asp.Net Web API 2第七课——Web API异常处理
- java 招聘需求_Java人员要具备哪些技能 招聘需求包括什么
- 【DotNetMLLearn】.NET Core人工智能系列-概述
- android:background大小,小Demo小知识-android:foreground与android:background
- c#之task与thread区别及其使用
- python网络爬虫系列(0)——爬虫概述 http协议复习
- 软件工程讲义 9 创新的出路 走进作坊
- 《高性能mysql》之MySQL高级特性(第七章)
- (HDRP)全局光照技术初探(一)-光照模式与阴影技术
- three.js加载OBJ格式模型(vue中使用three.js51)
- PHP腾讯云短信接口
- php获得视频文件扩展名,php 获取文件扩展名的 n 种方法
- LMIC一直busy解决方法
- 赋值,浅拷贝,深拷贝区别和实现方法
- 如何修复DNS劫持?dns被劫持了怎么办有什么解决方法
- 课时31 永久储存:腌制一缸美味的泡菜
- 树莓派呼吸灯python代码
热门文章
- 【软件设计原则】CUPID——快乐的编码
- mysql readtimeout_MySQL Timeout解析
- 弘辽科技:拼多多不交保证金商品有曝光量吗?怎么提升曝光?
- 链路聚合以及生成树(STP)
- http://www.le.com/ptv/vplay/23225570.html#vid=23225570
- thinkphp3.23开发的“二当家的”通用CMS系统
- 应用概率统计-第七章 数理统计的基本概念
- 2015年中国移动云计算平台市场发展趋势分析
- 全球与中国增强现实远程协助软件市场现状及未来发展趋势
- Multi-Port Switch模块用法