动态规划算法
来源:互联网 发布:大数据 nosql 编辑:程序博客网 时间:2024/06/05 19:52
1 动态规划的思想
动态规划也是采取的分治的思想,关键点就在于怎么去分。
在钢管分割的问题上,可以这样去思考问题,假设钢管长度为N,最优解是将其分割为k段。那么当将钢管分割为2段时,
我们假设x = L(1) + L(2) + ... + L(p), y = L(p+1) + L(p+2) + ... + L(k)。则必然是L(1) + L(2) + ... + L(p)是
长度为x的最优解,L(p+1) + L(p+2) + ... + L(k)是长度为y的最优解。证明方法很简单,采取反证的思想,如果
L(1) + L(2) + ... + L(p)不是长度为x的最优解,那么L(1) + L(2) + ... + L(p) + L(p+1) + L(p+2) + ... + L(k)必然
不是长度为n的最优解。
所以说将n分割为x+y的时候,并且通过一定次数的继续分割,必然会产生诸如L(1) + L(2) + ... + L(p) + L(p+1) + L(p+2) + ... + L(k)
的最优解。也就是说可以通过2分法来产生最优解,但是2分法的两个局部最优解的和就不一定是全局最优解了。
根据以上思想,可以得出钢管最优解的一个递归公式
r(n) = max(pn,(r1 + r(n-1)),(r2 + r(n-2)),...(r(n-1), r1));
2 问题的简化
可以这么想,将钢条分为两段,第一段的长度依次递加,那么所以递归式可以简化为:
r(n) = max(pi + r(n-i)), 1<=i<=n;
3 问题的解决
<1>直接用根据递推公式建立递归函数
这样的缺点就是会重复计算价值,造成资源的浪费
<2>建立起包含价值数组的递归函数
这是针对<1>的缺点,加入了价值数组,那么在用到长度为n的最大价值时候,如果r[n]已经存在,就不需要再次求解
<3>自底向上的迭代方法求解
这个比较简单和容易实现,它是不断的根据已经有的解来求解未知的解,从而得到最终的答案
4 代码实现
动态规划也是采取的分治的思想,关键点就在于怎么去分。
在钢管分割的问题上,可以这样去思考问题,假设钢管长度为N,最优解是将其分割为k段。那么当将钢管分割为2段时,
我们假设x = L(1) + L(2) + ... + L(p), y = L(p+1) + L(p+2) + ... + L(k)。则必然是L(1) + L(2) + ... + L(p)是
长度为x的最优解,L(p+1) + L(p+2) + ... + L(k)是长度为y的最优解。证明方法很简单,采取反证的思想,如果
L(1) + L(2) + ... + L(p)不是长度为x的最优解,那么L(1) + L(2) + ... + L(p) + L(p+1) + L(p+2) + ... + L(k)必然
不是长度为n的最优解。
所以说将n分割为x+y的时候,并且通过一定次数的继续分割,必然会产生诸如L(1) + L(2) + ... + L(p) + L(p+1) + L(p+2) + ... + L(k)
的最优解。也就是说可以通过2分法来产生最优解,但是2分法的两个局部最优解的和就不一定是全局最优解了。
根据以上思想,可以得出钢管最优解的一个递归公式
r(n) = max(pn,(r1 + r(n-1)),(r2 + r(n-2)),...(r(n-1), r1));
2 问题的简化
可以这么想,将钢条分为两段,第一段的长度依次递加,那么所以递归式可以简化为:
r(n) = max(pi + r(n-i)), 1<=i<=n;
3 问题的解决
<1>直接用根据递推公式建立递归函数
这样的缺点就是会重复计算价值,造成资源的浪费
<2>建立起包含价值数组的递归函数
这是针对<1>的缺点,加入了价值数组,那么在用到长度为n的最大价值时候,如果r[n]已经存在,就不需要再次求解
<3>自底向上的迭代方法求解
这个比较简单和容易实现,它是不断的根据已经有的解来求解未知的解,从而得到最终的答案
4 代码实现
#include <iostream>#include <algorithm>#include <vector>int cutRod(int* p, int n);int memoryCutRod(int* p, int n);int memoryCutRodAux(int* p, int n, std::vector<int>& r);int bottomUpCutRod(int*p, int n);int main(){int p[10] = {1,5,8,9,10,17,17,20,24,30};int n = 4;//first methodint r = cutRod(p, 4);std::cout << "max r:" << r << std::endl;//second methodr = memoryCutRod(p,4);std::cout << "max r:" << r << std::endl;//third mehodr = bottomUpCutRod(p, 4);std::cout << "max r:" << r << std::endl;return 0;}int cutRod(int* p, int n){if (n == 0)return 0;int q = INT_FAST32_MIN;for (int i = 1; i <= n; i++){q = std::max(q, p[i-1] + cutRod(p, n-i));}return q;}int memoryCutRod(int* p, int n){std::vector<int> r(n + 1, INT_FAST32_MIN);return memoryCutRodAux(p, n, r);}int memoryCutRodAux(int* p, int n, std::vector<int>& r){if (r[n] >= 0)return r[n];int q = INT_FAST32_MIN;if (n == 0)q = 0;else{for (int i = 1; i <= n; i++)q = std::max(q, p[i-1] + memoryCutRodAux(p, n-i, r));}r[n] = q;return q;}int bottomUpCutRod(int*p, int n){std::vector<int> r(n + 1, INT_FAST32_MIN);r[0] = 0;for (int j = 1; j <= n; j++){int q = INT_FAST32_MIN;for (int i = 1; i <= j; i++){q = std::max(q, p[i-1] + r[j-i]);}r[j] = q;}return r[n];}
5 输出
max r:10
max r:10
max r:10
6 参考
算法导论
0 0
- 算法--动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 初识动态规划算法
- 动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 动态规划算法实现
- 动态规划算法
- 动态规划算法
- 动态规划算法之一
- 动态规划算法备忘
- 动态规划 --压缩算法
- 动态规划算法
- 动态规划算法
- 动态规划算法解析
- JQ源码解析篇
- vue.js和angular.js的特点与比较
- CSU-1837 Tree Count(树的同构)
- Mysql之数据库备份与恢复
- blrlpbrzhjxrvjf
- 动态规划算法
- ztree+java后台取数据(包括异步)生成树状图
- vue.js和angular.js的数据展示
- spring-boot启动报错【This application has no explicit mapping for /error.....】
- CentOS6.8下JDK、Tomcat、MySQL搭建方法小结
- qaiyggwyswseiie
- 基于InnoDB索引主键策略
- 《大型网站技术架构:核心原理与案例分析》读书笔记
- sublime配置java编译运行