动态规划的关键和精妙之处
来源:互联网 发布:程序化交易软件下载 编辑:程序博客网 时间:2024/05/29 15:38
动态规划的思想大家都知道,将之前的计算结果存储起来,后面再用到时就直接拿来用,减少计算量。但实际操作确十分精妙,需要一定的技术含量。
有些是根据目的直接求(比如01背包),有些则是在计算过程中会出现最优解,进行比较得到(比如最大子数组和算法)
我从直接求解和过程出现解两个角度来解读动态规划。
01背包问题在求最大价值时涉及到包空间大小和物品个数,我们从两个维度进行考虑,第一纬是空间大小,第二位是物品个数。简单讲就是在求前m个物品(共n个物品),该物品占空间为k,在 i 大小空间(共 j 大小空间)时,前m-1个物品在1-j各个空间大小的最大值都已经知道了。所以此时最大价值有2种情况,一是第m个物品在保内,二是不在。第m个物品在包内时它的最大价值是第m个物品的价值加上前m-1个物品在j-k空间时的最大价值的和,因为第m个物品占去k空间后,剩下的就得由前m-1个物品填充得到最大价值了。当第m个物品不在包内时,则由前m-1个物品填充该空间,之前计算的结果直接拿来,两者取最大者即为前m个物品在i空间时的最大价值。以此类推就可以得到m个物品,在j空间能填充的最大价值。
注意,关键在于你要设计好前 i 空间、前m个物品的运算顺序,你也要设计好他们之间的关系,以及判断条件。
最大自数组的核心就是求得目前数组,从最后一位开始,到前面任意一位这段路程上的数据的和的最大值。比如此时计算到最后一位是第g位,则从第g位开始连续往前数
k (0=<k<g)位求得这k位数据的和,一共会有g中结果,取最大值。计算g+1位时,已知前g位从第g位开始到之前任意位置的最大数组和,第g+1位要么是第g位的结果加上g+1位的和,要么是第g+1位本身就是最大值。因为如果g+1位的结果(及从g+1位开始到之前任意一位这段数组和的最大值)到达了g+1位之间的位置,那么它一定会是第g位结果中数组前段的位置。这样当我们求到最大自数组的最后一位时,就会得到我们要的结果。
通过对两个动态规划原理的讲解,大家应该可以感觉到,动态规划的是设计一种递推关系,从小到大,它们之间有严密的逻辑关系,大的依赖小的,求大的时候需要进行条件判断,分类处理,借用之前的结果进行计算。
最最关键的是,你一定要明白决定这个最优解的决定性因素(如物品和空间),根据决定因素来进行条件判断和计算顺序设计,这是对01背包问题
最最关键的是,你要学会问题的转化,最大自数组和求的是包含n位的数组,从最后一位开始往前计算到任意一位的数组和的最大值,只是在计算中会出现我们需要的最优解。动规是从某个角度开始从小到大计算,计算某种最优解。但是这个最优解取决于你所相求的最优解,这个角度取决于这个最优解有关的或者决定这个最有解的因素。
简言之,就是动规计算过程中要根据所求解确定每次的最优解,根据最优解的决定、相关因素确定计算规模扩大的角度。同时设计好大小规模之间的关系,大规模如何通过条件判断来充分利用小规模的最优解,进而减少运算量。
- 动态规划的关键和精妙之处
- 【bzoj4011】【hnoi2015】落忆枫音【精妙的动态规划】
- 动态规划的关键 —— 子问题 & 公式化
- Bootstrap 栅格系统的精妙之处
- Bootstrap 栅格系统的精妙之处
- Java泛型的精妙之处
- Bootstrap栅格系统的精妙之处
- 【动态规划】之求连续子数组的最大和
- C++动态规划算法之子集的和
- 动态规划之矩阵的最小路径和
- 动态规划之背包问题,最基础的动态规划
- 【动态规划】 之 动态规划解题的一般思路
- 动态规划算法之最大字段和
- 动态规划之最大子段和
- 动态规划之LCS和LIS
- 动态规划之最大子段和
- 动态规划之最大子序列和
- CrackingtheCodeInterview之递归和动态规划
- MySQL常见问题及解决方案
- JAVA-反射机制(2)
- Notepad++编译解释java程序方法
- 《未来简史》中的十大脑洞
- 算法提高 ADV-71 判断回文
- 动态规划的关键和精妙之处
- 组合数算法
- JAVA实现五种排序算法
- 排序:桶排序
- lua 索引
- VS2010+gtest使用总结
- 把程序注册成windows后台进程
- scala闭包
- os, os.path模块中关于文件/目录常用的函数使用方法