算法设计与分析第三章:动态规划

 最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。保证算法的正确性。

重叠子问题性质。重叠子问题性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。

 应用范例

 矩阵连乘问题状态转移

这个问题的关键特征是:计算A[1:n]的最优次序所包含的矩阵子链A[1:k]和A[k+1:n]的次序也是最优的。我们可以反证来证明:如果A[1:n]的最优次序所包含的矩阵子链A[1:k]不是最优,那肯定有一个是比他次序少的,我们用其替换A[1:k],所得的A[1:n]将比先前的更少,也就是说A[1:n]不是最有次序,矛盾

 状态转移方程:

stra[i][j]=0                                                                           i=j;

stra[i][j]=min(i<=k<j){stra[i][k]+stra[k+1][j]+p(i-1)*p(k)*p(j)} i<j.

物理意义:

stra[i][j]表示矩阵A[i]到A[j]的最少数乘次数。

最长公共子序列

状态转移方程:

c[i][j]=0                                 i>0;j = 0

c[i][j]=c[i-1][j-1]+1                 i,j>0;xi = yi

c[i][j]=max{c[i][j-1],c[i-1][j]}   i,j>0;xi != yi

物理意义:

c[i][j]记录序列X前i位和序列Y前j位的最长公共子序列的长度。

最大子段和

状态转移方程:

dp[i]=max(dp[i-1]+a[i],a[i])      1<=i<=n

物理意义:

dp[i]表示前i和数的最大字段和

凸边型最优三角剖分

与矩阵连乘相似

状态转移方程:

dp[i][j]=0                                                                           i=j;

dp[i][j]=min(i<=k<j){dp[i][k]+dp[k+1][j]+w((vi-1)(vk)v(j))}   i<j.

物理意义:

dp[i][j](1<=i<j<=n)为子凸多边形((vi-1)(vi)...(vj) 的 最 优 三 角 剖 分 对 应 的 最 优 值 的最优三角剖分对应的最优值 的最优三角剖分对应的最优值
 

0-1背包问题

状态转移方程:

dp[i][j]=dp[i-1][j]                                        j<w[i]

dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])     j>=w[i]

物理意义:

dp[i][j]表示前i个物品容量为j时的最大价值

w[i]第i个物品的大小/体积

v[i]第i个物品的价值

最优二叉搜索树

状态转移方程:

e[i][j]=q i-1                                          j=i-1

e[i][j]=min(i<=r<=j){e[i][r-1]+e[r+1][j]+w(i,j) }      i<=j

物理意义:

qi为虚拟键闸查找概率

定义e[i,j]为包含关键字ki,...,kj的最优二叉查找树的期望代价。

对一棵关键字ki,...,kj的子树,定义其概率总和为:w(i,j)

带虚拟键最优二叉树详解

石子合并

n堆石子,可以化成n条直线问题,取最小值即可。下面就是对于每一条直线问题,我们如何解决。第一点,我们要明确这条直线是从哪里开始的;第二点,我们要明确直线包括了哪些石子。即起点和长度。针对第二种问题,我们可以用起点到终点来表示,但是对于环形而言,直线就转化为0->4, 1->0, 2->1, 3->2, 4->3,用数组不好表示。对于起点和长度,我们可以用二维数组,两个坐标分别表示起点和长度。比如dp[1][5]表示从编号为1的石堆开始,合并从1开始的5个石堆所需要的最小花费。

状态转移方程:

dp[i][n]=0                                      n=1;

dp[i][n]=min(dp[i][k]+dp[(i+k)%n][n-k]+getSum(i,n))  1<=k<=n

物理意义:

dp[i][n]是指从i起的n堆石子,dp[i][k]是从i起的k堆,k到k+1为间断点,还剩下n - k堆,是从编号为(i + k) % n的石堆开始的,合并这两堆的费用是getSum(i, n)。步长为1时,花费为0。从步长为2开始,对于每条直线,计算dp[i][n]的最值,直到n == N(总共的堆数)。dp[i][N]的最小值即为所求。

最小m段和

状态转移方程:

dp[i][j]=dp[i-1][j]+a[i]                                                                                        j=1

dp[i][j]=dp[i][j] = MIN(for(k=1; k<=i; k++)MAX(dp[k][j-1], dp[i][1] - dp[k][1]))    j>1

物理意义:

用dp[i][j]存储长度为i,分j段后其子序列和的最大值的最小值,这当中k表示的是分段的最后一段子序列的开始下标,所以dp[k][j-1]是前面j-1段子序列和的最大值的最小值,dp[i][1] - dp[k][1]是最后一段子序列的和。所以取这两段中的最大值,在k值变化过程中取得到的最小值。

最长递增子序列

状态转移方程:

dp[i]=1,    i为第一个字符的角标(0或1)

dp[i]=max(dp[i],dp[j]+1)      j<i;s[j]<s[i]

物理意义:

从左到右依次考虑,每遇到一个点就从第一位开始遍历到该点,看以这个点作为前缀是否为最大值。dp[i]表示以第i个字符结尾的最大递增子序列的长度.

优化

只管维持一个最小的递增子序列即可。End数组存最小递增子序列,遍历字符串,如果字符ch[i]比end数组的最后一个字符大,则添加至end数组后,计数加一;否则在end数组二分查找第一个大于等于ch[i]的字符,将其替换。遍历完后,计数器的值即为最优解。

独立任务最优调度

状态转移方程:

dp[i][j]=dp[i-1][j]+b[i]                                    other

dp[i][j]=min(dp[i-1][j-a[i]],dp[i-1][j]+b[i])        a[i]<=j<=sum[a[1..i]]

物理意义:

dp[i-1][j]+b[i]表示第i个作业A机器不去做,交给B机器做,B处理的时间;而dp[i-1][j-a[i]表示作业i由机器A处理,B不需要管,所以B机器处理的时间就是上一个作业的处理时间,即为dp[i-1][j-a[i]]。

又完成任务最短时间应该由A机器完成时间和B机器完成时间中最大的那一个决定。因为一项任务真正的完工需要等待两个同时完工才算完成。

我们可以明确了,在确定B机器处理时间时,我们会取最小值;当计算作业完成时间时,我们要取A、B中的最大值,最后还要取最小值才表示完成作业的最短时间(这里取的最小值是分配问题,即作业由A机器处理的时间会产生不同,我们先算出A处理所用的总时间,在这个时间范围内进行遍历,所有分配种类中取最小。)最优解为n个作业,所有分配情况,每个情况取A、B机器所用时间的较大值,再在所有较大值中取最小值,即为最优。

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Description 在讲动态规划课时,我们知道可用动态规划算法求解的问题应具备的一个基本要素是问题重叠性质,矩阵连乘问题能用动态规划求解正是因为它具有重叠问题。因此在解矩阵连乘问题的自顶向下的递归算法中,存在着大量的重叠问题计算。例如要计算4个矩阵A1A2A3A4最小连乘次数,要分别计算A1(A2A3A4)、(A1A2)(A3A4)和(A1A2A3)A4三种情况下的最小连乘次数,而计算A1(A2A3A4)的最小连乘次数要计算其问题A2A3A4的最小连乘次数,A2A3A4最小连乘次数的计算有二种情况(A2A3)A4和A2(A3A4),它分别包括求A2A3和A3A4两个问题。同理,计算(A1A2)(A3A4)包含A1A2和A3A4两个问题;计算(A1A2A3)A4包含计算A1A2A3、A1A2和A2A3这三个问题。故在解A1A2A3A4的最小连乘次数时,其问题的计算和重叠次数分别是: A1A2计算2次,重叠1次;A2A3计算2次,重叠1次;A3A4计算2次,重叠1次;A1A2A3只计算1次;A2A3A4只计算1次;A1A2A3A4只计算1次。因此,4个矩阵A1A2A3A4连乘的重叠问题分别为:A1A2、A2A3和A3A4的计算各重叠一次。现在你的编程任务是:对于n个矩阵连乘,求其重叠问题的计算次数。 Input 第一行是1个整数n(2≤n≤300),表示有n个矩阵连乘,接下来一行有n+1个数,表示是n个矩阵的行及第n个矩阵的列,它们之间用空格隔开. Output 输出重叠问题计算次数和对应的问题,中间以空格隔开,各问题重叠次数输出分别以A1、A2、… An打头的次序依次输出,格式如样例所示。如没有重叠问题输出NO Sample Input 4 30 35 15 5 10 Sample Output 1 A1A2 1 A2A3 1 A3A4

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值