动态规划算法学习总结
2021-07-09 20:06
标签:序号 单位 AMM seq 相同 多项式 efi 贪心 算法 贪心法在处理每个子问题时,不能回退,而动态规划可以保存之前的结果,择优选择。下面针对Interval Scheduling 问题,分析动态规划在实际问题中的应用。 如下图所示,每个长条方块代表一个工作,总有若干个工作a、b... h,横坐标是时间,方块的起点和终点分别代表这个工作的起始时间和结束时间。 当两个工作的工作时间没有交叉,即两个方块不重叠时,表示这两个工作是兼容的(compatible)。 当给每个工作赋权值都为1时,则称为 Unweighted Interval Scheduling 问题;当给每个工作赋不同的正权值时,则称为 Weighted Interval Scheduling 问题。 问题最终是要找到一个工作子集,集合内所有工作权值之和最大且集合内每个工作都兼容。 对于 Unweighted Interval Scheduling 问题,使用贪心算法即可求解,具体做法是按照结束时间对所有工作进行排序,然后从结束最晚的工作开始,依次排除掉与前一个不兼容的工作,剩下的工作所组成的集合即为所求。 然而,对于 Weighted Interval Scheduling 问题,贪心法找到的解可能不是最优的了。此时考虑使用动态规划算法解决问题,兼顾权值选择和兼容关系。 1、首先依然按照结束时间对所有的工作进行排序; 2、定义p(j)为在工作j之前,且与j兼容的工作的最大标号,通过分析每个工作的起始时间和结束时间,可以很容易计算出p(j); 3、例如下图所示,p(8)=5,因为工作7和6都与8不兼容,工作1到5都与8兼容,而5是其中索引最大的一个,所以p(8)=5。同理,p(7)=3,p(2)=0。 1、定义opt(j)是j个工作中,所能选择到的最佳方案,即opt(j)是最大的权值和; 2、对于第j个工作,有两种情况: 3、当j=0时,显示结果为0,这是边界条件。 后一步的结果取前一步所有可能情况的最大值,因此综上所述,能得到动态规划的递归关系为: 1、递归法 递归会使得空间复杂度变高,一般不建议使用。 2、自底向上法 从小到大进行计算,这样每次都可以利用前一步计算好的值来计算后一步的值,算法时间复杂度为O(nlogn),其中排序花费O(nlogn),后面的循环花费O(n)。 对于下图的例子,一种常见的贪心思想是:在背包可以装得下的情况下,尽可能选择价值更高的物品。那么当背包容量是W=11时,先选择item5,再选择item2,最后只能放下item1,总价值为28+6+1=35。实际上最优解是选择item3和item4,价值18+22=40。这说明了贪心算法对于背包问题的求解可能不是zuiyou的。下面考虑使用动态规划算法求解,首先要推导递归关系式。 类似于Weighted Interval Scheduling问题,定义opt(i, w)表示在有i个item,且背包剩余容量为w时所能得到的最大价值和。 考虑第i个item,有选和不选两种情况: 边界条件: 当i=0时,显然opt(i,w)=0。 后一步的结果取前一步所有可能情况的最大值,因此综上所述,能得到动态规划的递归关系为: 算法迭代过程如下表: 值得注意的是,该算法相对于输入尺寸来说,不是一个多项式算法,虽然O(nW)看起来很像一个多项式解,背包问题实际上是一个NP完全问题。 为了便于理解,可以写成这种形式: W在计算机中只是一个数字,以长度logW的空间存储,非常小。但是在实际运算中,随着W的改变,需要计算nW次,这是非常大的(相对于logW来说)。例如,当W为5kg的时候,以kg为基准单位,需要计算O(5n)次,当W为5t时,仍然以kg为单位,需要计算O(5000n)次,而在计算机中W的变化量相对很小。 给定两个序列x1,x2...xi和y1,y2,...,yj。要匹配这两个序列,使相似度足够大。首先需要定义一个表示代价的量-Edit distance,只有优化使这个量最小,就相当于最大化匹配了这两个序列。 Edit distance的定义如下所示。 其中,匹配到空,设距离为delta,否则字母p和q匹配的距离记为alpha(p,q),如果p=q,则alpha=0; 那么两个序列匹配的总代价为: 设opt(i,j)是序列x1,x2...xi和y1,y2,...,yj之间匹配所花费的最小代价。当i,j不全为0时,则分别有三种情况,分别是xi-gap,yj-gap,xi-yj,分别计算不同匹配情况所花费的代价,再加上前一步的结果,就可以建立递推关系式,如下所示。 时间和空间复杂度皆为O(mn)。 下面再分析一个具体的编程问题,使用动态规划算法,但是和上面的DP又有一些区别。 有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗? 输入描述 每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 ai(-50 。接下来的一行包含两个整数,k 和 d (1
输出描述 输出一行表示最大的乘积。 则无法实现“相邻两个学生的位置编号的差不超过 d”的要求。因此,需要定义一个辅助量,来包含对当前学生的定位信息。 其中,j是一个比i小的值,最大为i-1,i、j之差不超过D,f(j,k-1)表示在前j个学生中,选择k-1个学生,且第j个学生必选。f(i,k)选择了第i个学生,f(j,k-1)选择了第j个学生,i、j之差不超过D,这样就可以满足题目要求了。 动态规划算法学习总结 标签:序号 单位 AMM seq 相同 多项式 efi 贪心 算法 原文地址:https://www.cnblogs.com/Ran-Chen/p/9562225.html
动态规划与贪心、分治的区别
Interval Scheduling 问题
定义P(j)
分析递归关系
代码实现
Knapsack Problem 问题
背包问题的定义
推导递归关系式
自底向上求解
算法运行时间分析
Sequence Alignment
Define edit distance
建立递推关系
算法实现
算法复杂度
合唱团问题
问题定义
问题分析
代码实现
/*********************************************************************
*
* Ran Chen