动态规划(二)

动态规划应用举例之矩阵链乘法

矩阵链乘法问题
给定n个矩阵的链<A1,A2,...An>,矩阵Ai的规模为P(i-1)*Pi(1<=i<=n),求完全括号化方案,使得计算乘积A1A2...An所需标量乘法次数最少。
比如矩阵链<A1,A2,A3>相乘,不同的加括号方式会导致不同的计算代价。假定三个矩阵的规模为10*100、100*5、5*50。若按((A1A2)A3)计算,A1A2需要做10*100*5=5000次标量乘法(根据矩阵相乘代码得出所述计算方法),再与A3相乘又需要做10*5*50=2500次标量乘法,合起来共需7500次标量乘法。若按(A1(A2A3))的顺序,计算A2A3需要做100*5*50=25000次标量乘法,A1再与之相乘又需10*100*50=50000次标量乘法,合起来共需75000次标量乘法。
整体思路
为方便,用Aij表示AiA(i+1)...Aj乘积的结果矩阵。进行括号化,也就是在某个Ak和A(k+1)之间将矩阵链分开。所以,解决办法就是先计算矩阵A(i...k)的计算代价,加上矩阵A(k+1...j)的计算代价,再加上两者相乘的计算代价即为最小计算代价。
代码
MATRIX-CHAIN-ORDER(p)  
  for i=1 to n  //长度为1的链的最小计算代价为0
    m[i,j]=0
  for l=2 to n  //l代表链的长度,由小到大,因为链长的计算依赖于较短的链
    for i=1 to n-l+1  //根据链的长度计算所要求的m[i,j]中的i,i的最大值要有限定,否则有可能超出给定的矩阵链(比如矩阵链是0
                      //A2...A6,假定链长为3,那么i最大为4,若i=5,则需要A7。)
      j=i+l-1  //根据链的长度l和i的值计算j的值
      m[i,j]=100000000  //先给定一个比所有计算结果都大的值
      for k=i to j-1  //k为可能的矩阵链的分割点位置
        q=m[i,k]+m[k+1,j]+P(i-1)P(k)P(j)  //计算对应的代价
        if q<m[i,j]
          m[i,j]=q  //矩阵Aij所需标量乘法次数的最小值
          s[i,j]=k  //最优括号方案的分割点位置k
  return m and s

PRINT-OPTIMAL-PARENS(s,i,j)
  if i==j
    print "A";
  else 
    print "(" 
    PRINT-OPTIMAL-PARENS(s,i,s[i,j])
    PRINT-OPTIMAL-PARENS(s,s[i,j]+1,j)    print ")"     


动态规划应用举例之最长公共子序列

最长公共子序列问题
给定两个序列X=<x1,x2,...,xm>和Y=<y1,y2,...,yn>,求X和Y长度最长的公共子序列。

伪代码
LCS-LENGTH(X,Y)
  m=X.length
  n=Y.length
  for i=1 to m  //若一个序列长度为0,那么LCS的长度为0
    c[i,0]=0
  for j=0 to n  //同上
    c[0,j]=0
  for i=1 to m  由递归解计算LCS的长度
    for j=1 to n
      if xi==yi
        c[i,j]=c[i-1,j-1]+1
        b[i,j]="↖"  //表示xi=yj是LCS的一个元素
      else if c[i-1,j]>=c[i,j-1]
        c[i,j]=c[i-1,j]
        b[i,j]="↑"
      else
        c[i,j]=c[i,j-1]
        b[i,j]="←"
  return c and b
打印LCS
PRINT-LCS(b,X,i,j)
  if i==0 or j==0
    return 0
  if b[i,j]=="↖"
    PRINT-LCS(b,X,i-1,j-1)
    print xi
  else if b[i,j]=="↑"
    PRINT-LCS(b,X,i-1,j)
  else
    PRINT-LCS(b,X,i,j-1)








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值