动态规划
来源:互联网 发布:wows更新数据出错 编辑:程序博客网 时间:2024/06/03 09:56
什么是动态规划
个人理解是:将问题分解成相似的子过程或步骤,将大事化小,逐步求解的方式。
动态规划三个要素
- 最优子状态:将复杂问题简单化的过程,建模的第一步。比如计算N的斐波那契数值。可以先寻找N和N-1的关系:F(N)=F(N-1)+F(N-2); 这就最优子状态,将“大”问题往小了化解,个人认为这一步是最难的。
- 边界:问题最终可以通过动态规划来计算的关键,是最优子状态的最简单情况。比如斐波那契数列中的F(0)=1和F(1)=1;就是该问题的边界,是后续推导的起点。
- 状态转移公式:就是对上述两点的数学建模。斐波那契数列的公式就是他的状态转移公式
N = 0: F(0)=1
N = 1: F(1)=1
N > 1: F(N) = F(N-1) + F(N-2)
例子
举个今天从微信公众号“算法和数据结构”上的问题,我用Javascript实现了递归算法:
/** 问题:假设有N个金矿,M个矿工,每个金矿的产量为g[i],需要人工p[i],每个金矿必须足员才能开功,求最大开采量及开采的矿 动态规划法: 假设最大开采量公式为F(N,M); 最优子结构:找到N个矿和N-1个矿之间的关系 假设开采第N个矿,则最大开采量应该是Max(F(N-1,M-p[n])+g[n],F(N-1,M)); 假设不开采第N个矿,则最大开采量应该是F(N-1,M); 边界: 当N=1时,如果p[0] > M,则最大开采量为g[0]; 如果p[0] < M,则最大开采量为0; 状态转换公式: p[n] > M : F(N-1,M); p[n] < M : Max(F(N-1,M-p[n])+g[n],F(N-1,M));**/ function findWayToDig(w,ar){ if(ar.length<1){ console.log("The init array is empty!!!"); } if(ar.length==1){ if(ar[0].ppl > w ){ return 0; }else{ return ar[0].amt; } } var amt = ar[0].amt; var ppl = ar[0].ppl; var next = ar.slice(1); if(ppl > w){ return findWayToDig(w,next); }else{ return Math.max(amt + findWayToDig(w-ppl,next),findWayToDig(w,next)); }}(function(){ var ar =[{amt:500,ppl:5}, {amt:200,ppl:3},{ amt:300,ppl:4 }, {amt:350,ppl:3}, {amt:400,ppl:5}]; console.log(findWayToDig(10,ar)); })();
- 首先上述方法有优化空间,可以增加一个临时对象保存历史计算结果findWayToDig(w,next)。
- 其次还可以使用迭代法(正向推导)来实现,这部分有空补上。
阅读全文
0 0
- 动态规划!!!动态规划!!!
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 如何发布Web项目到互联网
- Stack Overflow 2017 开发者调查报告(程序员必看)
- centos安装docker
- Flex 布局教程:语法篇
- 选择微服务部署策略
- 动态规划
- less-带参数的混合(arguments)
- ubtun安装docker
- 盐水的故事
- 解析TCP三次握手四次挥手
- ACdream 1084 寒假安排 (数学题)
- 前言--你也可以成为量子计算机程序员
- iOS 本地通知
- Leetcode:523. Continuous Subarray Sum