【算法】动态规划(矩阵连乘问题、最长公共子序列、0-1背包问题)

本文深入讲解动态规划算法,包括其基本思想、应用步骤、及在矩阵连乘、最长公共子序列、0-1背包问题中的具体实现。通过实例剖析,揭示动态规划与分治法的区别,强调利用表记录子问题解的重要性。

动态规划

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适用于用动态规划求解问题的时候,经分解得到的子问题往往不是相互独立的。若用分治法解这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要消耗指数时间。然而,不同子问题的数目常常只有多项式量级。在用分治法求解时,有些子问题被重复计算了许多次。如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复的计算,从而得到多项式时间算法。为了达到这个目的,可以用一个表来记录所有已解决的子问题的答案。不管该子问题以后是否被利用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思想。具体的动态规划算法是多种多样的,但它们具有相同的填表格式。

动态规划算法适用于解最优化问题。通常可以按以下步骤设计动态规划算法:

  1. 找出最优解的性质,并刻画其结构特征。
  2. 递归地定义最优值
  3. 以自底向上的方式计算出最优值
  4. 根据计算最优值时得到的信息,构造最优解

矩阵连乘问题(最优计算次序问题)

什么是矩阵连乘?
当前一个矩阵的行数等于下一个矩阵的列数,就可以进行矩阵乘法运算,如果给定n个矩阵{A1,A2,……An}其中两两矩阵是可乘的,(23,34,4*5……)这就是矩阵连乘。

那我们每次都要按顺序乘吗?
由于乘法满足结合律,所以我们有多种选择。比如A1A2A3A4就有五种乘法
(A1(A2(A3A4)))
(A1((A2A3)A4))
((A1A2)(A3A4))
((A1(A2A3))A4)
(((A1A2)A3)A4)
那这些选择导致的结果一样吗?
结果是一样,但如果我们考虑到计算效率的问题(计算量),就值得深究了。
两个矩阵连乘的计算量:是前一个矩阵的行和列后一个矩阵的列
(3
2*3)
在这里插入图片描述
给出计算两个矩阵相乘的计算量的代码

 public static void MatrixMultiply(int [][]a,int [][]b,int [][]c,
                                      int ra,int ca,int rb,int cb)
    {
        if(ca != rb)  {    }
        for(int i = 0;i < ra; ++i)
        {
            for(int j = 0;j<cb; ++j)
            {
                int tmp = 0;
                for (int k = 0; k < ca; ++k)
                {
                    tmp += a[i][k] * b[k][j];
                }
                c[i][j] = tmp;
            }
        }
    }

比如 5100 1008 860这三个矩阵相乘;
1)(5
100 1008)860
先计算前两个矩阵相乘,这样需要乘51008次,然后再和第三个矩阵乘 总共需要51008+5860=6400次
2)5100(1008860)
先计算后两个,需要乘100
860次,然后在和第一个相乘,总共需要100860+5100*60=78000次
这样经过对比,很明显前者的计算次数少很多,效率更高,所以我们在计算矩阵连乘时,不能使用穷举搜索法一个个计算,而是要使用方法,否则offer便飞走了。

我们现在考虑用动态规划来解决?

第一步:分析最优解结构

假设i–j个矩阵
简记为A【i,j】 我们可以在Ak和Ak+1之间断开为 A【i,k】【 k+1,j】
按照此次序,先计算i–k,再计算k+1–j 然后再加上A【i,k】和A【 k+1,j】相乘的计算量就是总共的计算量了。这里的每个部分如果取到最优解,那么结果便是最优解。
矩阵连乘计算次序问题的最优解包含着其子问题的最优解。这种性质称为最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法求解的显著特征。

第二步:建立递归关系

我一直觉得动态规划和递归与分治策略思想分不开,可以说动态规划是递归与分治策略的升华。

而找到递归关系我们需要清楚什么时候从递归退出:
当i==j时,矩阵为单一矩阵,无需计算 计算量m【i】【j】=0
当i<j时,m【i】【j】=min{m【i】【k】+m【k+1】【j】+qqq}(k=i,i+1……j-1)

根据最优解结构可以知道qqq就是A【i,k】和A【 k+1,j】相乘的计算量了,那具体怎么算呢?
假如矩阵的维数给定
A1 A2 A3 A4
36 68 87 715
将维数入到数组里:p=【3,6,8,7,15】重复的不入
当k=2时,也就是从第二个划分开,则 A【1,2】和A【 3,4】相乘的计算量=3815 ,也就是**p[i-1]p[k]p[j]

所以最后的表达式为:
在这里插入图片描述

3、计算最优值

其实我们要做的就是把数学公式用代码表示出来。
可是如果我们只用递归算法计算,可以看到将耗费指数时间。在递

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值